4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Sample/Sample/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIMainStoryboardFile
26 | Main
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 | UIInterfaceOrientationLandscapeLeft
35 | UIInterfaceOrientationLandscapeRight
36 |
37 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/Sample/Sample/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Sample/Sample/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/Sample/Gemfile.lock:
--------------------------------------------------------------------------------
1 | GEM
2 | remote: http://gems.ruby-china.org/
3 | specs:
4 | CFPropertyList (3.0.0)
5 | activesupport (4.2.10)
6 | i18n (~> 0.7)
7 | minitest (~> 5.1)
8 | thread_safe (~> 0.3, >= 0.3.4)
9 | tzinfo (~> 1.1)
10 | atomos (0.1.2)
11 | claide (1.0.2)
12 | cocoapods (1.5.2)
13 | activesupport (>= 4.0.2, < 5)
14 | claide (>= 1.0.2, < 2.0)
15 | cocoapods-core (= 1.5.2)
16 | cocoapods-deintegrate (>= 1.0.2, < 2.0)
17 | cocoapods-downloader (>= 1.2.0, < 2.0)
18 | cocoapods-plugins (>= 1.0.0, < 2.0)
19 | cocoapods-search (>= 1.0.0, < 2.0)
20 | cocoapods-stats (>= 1.0.0, < 2.0)
21 | cocoapods-trunk (>= 1.3.0, < 2.0)
22 | cocoapods-try (>= 1.1.0, < 2.0)
23 | colored2 (~> 3.1)
24 | escape (~> 0.0.4)
25 | fourflusher (~> 2.0.1)
26 | gh_inspector (~> 1.0)
27 | molinillo (~> 0.6.5)
28 | nap (~> 1.0)
29 | ruby-macho (~> 1.1)
30 | xcodeproj (>= 1.5.7, < 2.0)
31 | cocoapods-core (1.5.2)
32 | activesupport (>= 4.0.2, < 6)
33 | fuzzy_match (~> 2.0.4)
34 | nap (~> 1.0)
35 | cocoapods-deintegrate (1.0.2)
36 | cocoapods-downloader (1.2.0)
37 | cocoapods-plugins (1.0.0)
38 | nap
39 | cocoapods-search (1.0.0)
40 | cocoapods-stats (1.0.0)
41 | cocoapods-trunk (1.3.0)
42 | nap (>= 0.8, < 2.0)
43 | netrc (~> 0.11)
44 | cocoapods-try (1.1.0)
45 | colored2 (3.1.2)
46 | concurrent-ruby (1.0.5)
47 | escape (0.0.4)
48 | fourflusher (2.0.1)
49 | fuzzy_match (2.0.4)
50 | gh_inspector (1.1.3)
51 | i18n (0.9.5)
52 | concurrent-ruby (~> 1.0)
53 | minitest (5.11.3)
54 | molinillo (0.6.5)
55 | nanaimo (0.2.5)
56 | nap (1.1.0)
57 | netrc (0.11.0)
58 | ruby-macho (1.1.0)
59 | thread_safe (0.3.6)
60 | tzinfo (1.2.5)
61 | thread_safe (~> 0.1)
62 | xcodeproj (1.5.7)
63 | CFPropertyList (>= 2.3.3, < 4.0)
64 | atomos (~> 0.1.2)
65 | claide (>= 1.0.2, < 2.0)
66 | colored2 (~> 3.1)
67 | nanaimo (~> 0.2.4)
68 |
69 | PLATFORMS
70 | ruby
71 |
72 | DEPENDENCIES
73 | cocoapods (~> 1.5.0)
74 |
75 | RUBY VERSION
76 | ruby 2.3.3p222
77 |
78 | BUNDLED WITH
79 | 1.16.1
80 |
--------------------------------------------------------------------------------
/Sample/Sample/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // Sample
4 | //
5 | // Created by 李二狗 on 2018/6/5.
6 | // Copyright © 2018年 Meniny Lab. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 |
16 |
17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
18 | // Override point for customization after application launch.
19 | return true
20 | }
21 |
22 | func applicationWillResignActive(_ application: UIApplication) {
23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
24 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
25 | }
26 |
27 | func applicationDidEnterBackground(_ application: UIApplication) {
28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
30 | }
31 |
32 | func applicationWillEnterForeground(_ application: UIApplication) {
33 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
34 | }
35 |
36 | func applicationDidBecomeActive(_ application: UIApplication) {
37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
38 | }
39 |
40 | func applicationWillTerminate(_ application: UIApplication) {
41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
42 | }
43 |
44 |
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/Sample/Sample/ViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // Sample
4 | //
5 | // Created by 李二狗 on 2018/6/5.
6 | // Copyright © 2018年 Meniny Lab. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import EASegments
11 |
12 | class ViewController: UIViewController, EASegmentsDelegate {
13 |
14 | @IBOutlet weak var segmentsViaIB: EASegments!
15 | let flamingo = #colorLiteral(red: 0.92, green: 0.38, blue: 0.25, alpha: 1.00)
16 | let carmine = #colorLiteral(red: 0.70, green: 0.28, blue: 0.15, alpha: 1.00)
17 |
18 | override func viewDidLoad() {
19 | super.viewDidLoad()
20 | // Do any additional setup after loading the view, typically from a nib.
21 |
22 | UIApplication.shared.statusBarStyle = .lightContent
23 | navigationController?.navigationBar.isTranslucent = false
24 | navigationController?.navigationBar.barTintColor = flamingo
25 |
26 | segmentsViaIB.titles = ["EASegments", "Yay!"]
27 |
28 | segmentsViaIB.backgroundColor = flamingo
29 | segmentsViaIB.selectedBackgroundColor = .white
30 |
31 | segmentsViaIB.titleColor = .white
32 | segmentsViaIB.selectedTitleColor = flamingo
33 |
34 | segmentsViaIB.titleFont = UIFont(name: "HelveticaNeue-Light", size: 17.0)
35 |
36 | self.setup()
37 | }
38 |
39 | func setup() {
40 | let segments = EASegments(titles: ["Tweets", "Likes"])
41 | // use frame, or AutoLayout
42 | segments.frame = CGRect(x: 0, y: 0, width: 200.0, height: 30.0)
43 |
44 | segments.backgroundColor = carmine
45 | segments.selectedBackgroundColor = .white
46 |
47 | segments.titleColor = .white
48 | segments.selectedTitleColor = flamingo
49 |
50 | segments.titleFont = UIFont(name: "HelveticaNeue-Medium", size: 13.0)
51 |
52 | // do this:
53 | // segments.addTarget(self, action: #selector(segmentsValueDidChange(_:)), for: .valueChanged)
54 | // or this:
55 | segments.delegate = self // EASegmentsDelegate?
56 |
57 | navigationItem.titleView = segments
58 | }
59 |
60 | // addTarget
61 | @objc
62 | @IBAction func segmentsValueDidChange(_ sender: EASegments) {
63 | print("valueChanged: \(sender.selectedIndex) [\(sender.selectedTitle ?? "nil")]")
64 | }
65 |
66 | // EASegmentsDelegate
67 | func segments(_ segments: EASegments, didSelectAt index: Int) {
68 | print("didSelectAt: \(segments.selectedIndex) [\(segments.selectedTitle ?? "nil")]")
69 | }
70 |
71 | override func didReceiveMemoryWarning() {
72 | super.didReceiveMemoryWarning()
73 | // Dispose of any resources that can be recreated.
74 | }
75 |
76 |
77 | }
78 |
79 |
--------------------------------------------------------------------------------
/README.adoc:
--------------------------------------------------------------------------------
1 | :name: EASegments
2 | :author: Elias Abel
3 | :author_esc: Elias%20Abel
4 | :mail: admin@meniny.cn
5 | :desc: a segments control for iOS
6 | :icon: {name}.png
7 | :version: 1.0.1
8 | :na: N/A
9 | :ios: 8.0
10 | :macos: {na}
11 | :watchos: {na}
12 | :tvos: {na}
13 | :linux: {na}
14 | :xcode: 9.3
15 | :swift: 4.1
16 | :license: MIT
17 | :sep: %20%7C%20
18 | :platform: iOS
19 | // :toc: left
20 | :toclevels: 6
21 | :toc-title: TOC
22 | :source-highlighter: highlightjs
23 | // :source-highlighter: pygments
24 | = Meet `{name}`
25 | {author} <{mail}>
26 | v{version}, 2018-05-08
27 |
28 | [subs="attributes"]
29 | ++++
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 | ++++
47 |
48 | :toc:
49 |
50 | == 🏵 Introduction
51 |
52 | **{name}** is {desc}.
53 |
54 | image::./Assets/Preivew-Tap.gif[Preivew-Tap.gif]
55 |
56 | image::./Assets/Preview-Pan.gif[Preview-Pan.gif]
57 |
58 | == 📋 Requirements
59 |
60 | [%header]
61 | |===
62 | 2+^m|Type 1+^m|Requirement
63 |
64 | 1.5+^.^|Platform ^|iOS ^|{ios}+
65 | ^|macOS ^|{macos}
66 | ^|tvOS ^|{tvos}
67 | ^|watchOS ^|{watchos}
68 | ^|Linux ^|{linux}
69 |
70 | ^|IDE ^|Xcode ^| {xcode}+
71 | ^|Language ^|Swift ^| {swift}+
72 | |===
73 |
74 | == 📲 Installation
75 |
76 | === CocoaPods
77 |
78 | `{name}` is available on link:https://cocoapods.org[CocoaPods].
79 |
80 | [source, ruby, subs="verbatim,attributes"]
81 | ----
82 | use_frameworks!
83 | pod '{name}'
84 | ----
85 |
86 | === Manually
87 |
88 | Copy all files in the `{name}` directory into your project.
89 |
90 | == 🛌 Dependency
91 |
92 | {na}
93 |
94 | == ❤️ Contribution
95 |
96 | You are welcome to fork and submit pull requests.
97 |
98 | == 🔖 License
99 |
100 | `{name}` is open-sourced software, licensed under the link:./LICENSE.md[`{license}`] license.
101 |
102 | == 🔫 Usage
103 |
104 | [source, swift, subs="verbatim,attributes"]
105 | ----
106 | import {name}
107 |
108 | func setup() {
109 | let flamingo = #colorLiteral(red: 0.92, green: 0.38, blue: 0.25, alpha: 1.00)
110 |
111 | let segments = EASegments(titles: ["Tweets", "Likes"])
112 | // use frame, or AutoLayout
113 | segments.frame = CGRect(x: 30.0, y: 40.0, width: 200.0, height: 30.0)
114 |
115 | segments.backgroundColor = flamingo
116 | segments.selectedBackgroundColor = .white
117 |
118 | segments.titleColor = .white
119 | segments.selectedTitleColor = flamingo
120 |
121 | segments.titleFont = UIFont(name: "HelveticaNeue-Medium", size: 13.0)
122 |
123 | // do this:
124 | // segments.addTarget(self, action: #selector(segmentsValueDidChange(:)), for: .valueChanged)
125 | // or this:
126 | segments.delegate = self // EASegmentsDelegate?
127 |
128 | someView.addSubview(segments)
129 | }
130 |
131 | // addTarget
132 | @objc
133 | func segmentsValueDidChange(_ sender: EASegments) {
134 | print("valueChanged: \(sender.selectedIndex) [\(sender.selectedTitle ?? "nil")]")
135 | }
136 |
137 | // EASegmentsDelegate
138 | func segments(_ segments: EASegments, didSelectAt index: Int) {
139 | print("didSelectAt: \(segments.selectedIndex) [\(segments.selectedTitle ?? "nil")]")
140 | }
141 | ----
142 |
--------------------------------------------------------------------------------
/Sample/.swiftlint.yml:
--------------------------------------------------------------------------------
1 | # --------------------------------------
2 | disabled_rules: # Rules can be disabled, to mark a rule as disabled, please enter below:
3 | - type_name # e.g. typealias startWithALowerLetterTypeName = String
4 | - identifier_name # e.g. var contains_non_alphanumeric_characters, _underlineStartedName
5 | - shorthand_operator # e.g. abc = abc + 1
6 | - line_length # A line witch is too long
7 | - cyclomatic_complexity # A function witch is to complexity, e.g. too many parameters
8 | - trailing_whitespace # Lines should not have trailing whitespace
9 | - trailing_newline # Files should have a single trailing newline
10 | - todo # FIXMEs should be avoided
11 | - redundant_string_enum_value # String enum values can be omitted when they are equal to the enumcase name
12 | - function_parameter_count # Function should have 5 parameters or less
13 | - multiple_closures_with_trailing_closure # Trailing closure syntax should not be used when passing more than one closure argument
14 | - file_length # File should contain 400 lines or less
15 | - nesting # Types should be nested at most 1 level deep
16 | - vertical_whitespace
17 | - operator_whitespace
18 |
19 | # --------------------------------------
20 | opt_in_rules: # `opt_in_rules` are disabled by default, to mark a rule as opt-in, please enter below:
21 | - fatal_error_message
22 |
23 | # --------------------------------------
24 | #whitelist_rules: # Acts as a whitelist, only the rules specified in this list will be enabled. Can not be specified alongside `disabled_rules` or `opt_in_rules`.
25 |
26 | # --------------------------------------
27 | #included: # # paths to include during linting. `--path` is ignored if present.
28 |
29 | # --------------------------------------
30 | excluded: # Paths to ignore during linting. Takes precedence over `included`.
31 | - Carthage
32 | - Pods
33 |
34 | # --------------------------------------
35 | # configurable rules can be customized from this configuration file
36 | # binary rules can set their severity level
37 | force_cast: warning # e.g. 123 as! Data
38 | force_try: # e.g. try! someThrowsFunction()
39 | severity: warning
40 | type_body_length:
41 | warning: 300
42 | error: 400
43 | file_length:
44 | warning: 1000
45 | error: 1500
46 | function_body_length:
47 | warning: 100
48 | error: 250
49 |
50 | # --------------------------------------
51 | custom_rules:
52 | new_line_after_method_signature: # rule identifier
53 | included: ".*\\.swift" # regex that defines paths to include during linting. optional.
54 | excluded: ".*\\.yml" # regex that defines paths to exclude during linting. optional
55 | name: "New line after method signature" # rule name. optional.
56 | regex: "(\\{(\\n\\s*){3,}\\w)" # matching pattern
57 | match_kinds: # SyntaxKinds to match. optional.
58 | - argument
59 | - attribute.builtin
60 | - attribute.id
61 | - buildconfig.id
62 | - buildconfig.keyword
63 | - comment
64 | - comment.mark
65 | - comment.url
66 | - doccomment
67 | - doccomment.field
68 | - identifier
69 | - keyword
70 | - number
71 | - objectliteral
72 | - parameter
73 | - placeholder
74 | - string
75 | - string_interpolation_anchor
76 | - typeidentifier
77 | message: "No new line after curly braces and before code." # violation message. optional.
78 | severity: warning # violation severity. optional.
79 |
80 | error_comment:
81 | included: ".*\\.swift"
82 | excluded: ".*\\.yml"
83 | name: "⁉️ ERROR"
84 | regex: "// (ERROR|FATAL):"
85 | match_kinds:
86 | - comment
87 | message: "You HAVE TO fix this ERROR."
88 | severity: error
89 |
90 | unnecessary_floating_zero:
91 | included: ".*\\.swift"
92 | excluded: ".*\\.yml"
93 | name: "Unnecessary floating zero"
94 | regex: "(?
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
--------------------------------------------------------------------------------
/EASegments/EASegments.swift:
--------------------------------------------------------------------------------
1 | //
2 | // EASegments.swift
3 | // EASegments
4 | //
5 | // Created by Elias Abel on 9/3/17.
6 | // Copyright © 2017 Meniny Lab. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | // MARK: - EASegmentsRoundedLayer
12 |
13 | open class EASegmentsRoundedLayer: CALayer {
14 | override open var bounds: CGRect {
15 | didSet { cornerRadius = bounds.height / 2.0 }
16 | }
17 | }
18 |
19 | public protocol EASegmentsDelegate: class {
20 | func segments(_ segments: EASegments, didSelectAt index: Int)
21 | }
22 |
23 | // MARK: - EASegments
24 |
25 | @IBDesignable
26 | open class EASegments: UIControl {
27 |
28 | // MARK: - Public vars
29 |
30 | open var titles: [String] {
31 | set {
32 | (titleLabels + selectedTitleLabels).forEach { $0.removeFromSuperview() }
33 | titleLabels = newValue.map { title in
34 | let label = UILabel()
35 | label.text = title
36 | label.textColor = titleColor
37 | label.font = titleFont
38 | label.textAlignment = .center
39 | label.lineBreakMode = .byTruncatingTail
40 | titleLabelsContentView.addSubview(label)
41 | return label
42 | }
43 | selectedTitleLabels = newValue.map { title in
44 | let label = UILabel()
45 | label.text = title
46 | label.textColor = selectedTitleColor
47 | label.font = titleFont
48 | label.textAlignment = .center
49 | label.lineBreakMode = .byTruncatingTail
50 | selectedTitleLabelsContentView.addSubview(label)
51 | return label
52 | }
53 | }
54 | get { return titleLabels.map { $0.text! } }
55 | }
56 |
57 | open weak var delegate: EASegmentsDelegate?
58 |
59 | open fileprivate(set) var selectedIndex: Int = 0 {
60 | didSet {
61 | self.delegate?.segments(self, didSelectAt: self.selectedIndex)
62 | }
63 | }
64 |
65 | open var selectedTitle: String? {
66 | guard selectedIndex >= 0 && selectedIndex < titles.count else {
67 | return nil
68 | }
69 | return titles[selectedIndex]
70 | }
71 |
72 | open var selectedBackgroundInset: CGFloat = 2.0 {
73 | didSet { setNeedsLayout() }
74 | }
75 |
76 | @IBInspectable
77 | open var selectedBackgroundColor: UIColor! {
78 | set { selectedBackgroundView.backgroundColor = newValue }
79 | get { return selectedBackgroundView.backgroundColor }
80 | }
81 |
82 | @IBInspectable
83 | open var titleColor: UIColor! {
84 | didSet { titleLabels.forEach { $0.textColor = titleColor } }
85 | }
86 |
87 | @IBInspectable
88 | open var selectedTitleColor: UIColor! {
89 | didSet { selectedTitleLabels.forEach { $0.textColor = selectedTitleColor } }
90 | }
91 |
92 | open var titleFont: UIFont! {
93 | didSet { (titleLabels + selectedTitleLabels).forEach { $0.font = titleFont } }
94 | }
95 |
96 | @IBInspectable
97 | open var titleFontFamily: String = "HelveticaNeue"
98 |
99 | @IBInspectable
100 | open var titleFontSize: CGFloat = 18
101 |
102 | open var animationDuration: TimeInterval = 0.3
103 | open var animationSpringDamping: CGFloat = 0.75
104 | open var animationInitialSpringVelocity: CGFloat = 0
105 |
106 | // MARK: - Private vars
107 |
108 | open fileprivate(set) var titleLabelsContentView = UIView.init(frame: .zero)
109 | open fileprivate(set) var titleLabels = [UILabel]()
110 |
111 | open fileprivate(set) var selectedTitleLabelsContentView = UIView.init(frame: .zero)
112 | open fileprivate(set) var selectedTitleLabels = [UILabel]()
113 |
114 | open fileprivate(set) var selectedBackgroundView = UIView.init(frame: .zero)
115 |
116 | open fileprivate(set) var titleMaskView: UIView = UIView.init(frame: .zero)
117 |
118 | open fileprivate(set) var tapGesture: UITapGestureRecognizer!
119 | open fileprivate(set) var panGesture: UIPanGestureRecognizer!
120 |
121 | open fileprivate(set) var initialSelectedBackgroundViewFrame: CGRect?
122 |
123 | // MARK: - Constructors
124 |
125 | public convenience init(titles: String...) {
126 | self.init(titles: titles)
127 | }
128 |
129 | public init(titles: [String]) {
130 | super.init(frame: CGRect.zero)
131 | self.titles = titles
132 | finishInit()
133 | }
134 |
135 | required public init?(coder aDecoder: NSCoder) {
136 | super.init(coder: aDecoder)
137 | finishInit()
138 | }
139 |
140 | override public init(frame: CGRect) {
141 | super.init(frame: frame)
142 | finishInit()
143 | backgroundColor = .black // don't set background color in finishInit(), otherwise IB settings which are applied in init?(coder:) are overwritten
144 | }
145 |
146 | fileprivate func finishInit() {
147 | // Setup views
148 | addSubview(titleLabelsContentView)
149 |
150 | object_setClass(selectedBackgroundView.layer, EASegmentsRoundedLayer.self)
151 | addSubview(selectedBackgroundView)
152 |
153 | addSubview(selectedTitleLabelsContentView)
154 |
155 | object_setClass(titleMaskView.layer, EASegmentsRoundedLayer.self)
156 | titleMaskView.backgroundColor = .black
157 | selectedTitleLabelsContentView.layer.mask = titleMaskView.layer
158 |
159 | // if #available(iOS 9.0, *) {
160 | // titleMaskView.leftAnchor.constraint(equalTo: selectedBackgroundView.leftAnchor)
161 | // titleMaskView.topAnchor.constraint(equalTo: selectedBackgroundView.topAnchor)
162 | // titleMaskView.widthAnchor.constraint(equalTo: selectedBackgroundView.widthAnchor)
163 | // titleMaskView.heightAnchor.constraint(equalTo: selectedBackgroundView.heightAnchor)
164 | // }
165 |
166 | // Setup defaul colors
167 | if backgroundColor == nil {
168 | backgroundColor = .black
169 | }
170 |
171 | selectedBackgroundColor = .white
172 | titleColor = .white
173 | selectedTitleColor = .black
174 |
175 | // Gestures
176 | tapGesture = UITapGestureRecognizer(target: self, action: #selector(tapped))
177 | addGestureRecognizer(tapGesture)
178 |
179 | panGesture = UIPanGestureRecognizer(target: self, action: #selector(pan))
180 | panGesture.delegate = self
181 | addGestureRecognizer(panGesture)
182 |
183 | selectedBackgroundView.addObserver(self, forKeyPath: "frame", options: .new, context: nil)
184 | }
185 |
186 | override open func awakeFromNib() {
187 | super.awakeFromNib()
188 | self.titleFont = UIFont(name: self.titleFontFamily, size: self.titleFontSize)
189 | }
190 |
191 | // MARK: - Destructor
192 |
193 | deinit {
194 | selectedBackgroundView.removeObserver(self, forKeyPath: "frame")
195 | }
196 |
197 | // MARK: - Observer
198 |
199 | override open func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
200 | if keyPath == "frame" {
201 | titleMaskView.frame = selectedBackgroundView.frame
202 | }
203 | }
204 |
205 | // MARK: -
206 |
207 | override open class var layerClass : AnyClass {
208 | return EASegmentsRoundedLayer.self
209 | }
210 |
211 | @objc func tapped(_ gesture: UITapGestureRecognizer!) {
212 | let location = gesture.location(in: self)
213 | let index = Int(location.x / (bounds.width / CGFloat(titleLabels.count)))
214 | setSelectedIndex(index, animated: true)
215 | }
216 |
217 | @objc func pan(_ gesture: UIPanGestureRecognizer!) {
218 | if gesture.state == .began {
219 | initialSelectedBackgroundViewFrame = selectedBackgroundView.frame
220 | } else if gesture.state == .changed {
221 | var frame = initialSelectedBackgroundViewFrame!
222 | frame.origin.x += gesture.translation(in: self).x
223 | frame.origin.x = max(min(frame.origin.x, bounds.width - selectedBackgroundInset - frame.width), selectedBackgroundInset)
224 | selectedBackgroundView.frame = frame
225 | } else if gesture.state == .ended || gesture.state == .failed || gesture.state == .cancelled {
226 | let index = max(0, min(titleLabels.count - 1, Int(selectedBackgroundView.center.x / (bounds.width / CGFloat(titleLabels.count)))))
227 | setSelectedIndex(index, animated: true)
228 | }
229 | }
230 |
231 | open func setSelectedIndex(_ selectedIndex: Int, animated: Bool) {
232 | guard 0.. Void in
246 | self.layoutSubviews()
247 | }, completion: nil)
248 | } else {
249 | layoutSubviews()
250 | sendActions(for: .valueChanged)
251 | }
252 | }
253 |
254 | // MARK: - Layout
255 |
256 | override open func layoutSubviews() {
257 | super.layoutSubviews()
258 |
259 | let selectedBackgroundWidth = bounds.width / CGFloat(titleLabels.count) - selectedBackgroundInset * 2.0
260 | selectedBackgroundView.frame = CGRect(x: selectedBackgroundInset + CGFloat(selectedIndex) * (selectedBackgroundWidth + selectedBackgroundInset * 2.0), y: selectedBackgroundInset, width: selectedBackgroundWidth, height: bounds.height - selectedBackgroundInset * 2.0)
261 |
262 | (titleLabelsContentView.frame, selectedTitleLabelsContentView.frame) = (bounds, bounds)
263 |
264 | let titleLabelMaxWidth = selectedBackgroundWidth
265 | let titleLabelMaxHeight = bounds.height - selectedBackgroundInset * 2.0
266 |
267 | zip(titleLabels, selectedTitleLabels).forEach { label, selectedLabel in
268 | let index = titleLabels.index(of: label)!
269 |
270 | var size = label.sizeThatFits(CGSize(width: titleLabelMaxWidth, height: titleLabelMaxHeight))
271 | size.width = min(size.width, titleLabelMaxWidth)
272 |
273 | let x = floor((bounds.width / CGFloat(titleLabels.count)) * CGFloat(index) + (bounds.width / CGFloat(titleLabels.count) - size.width) / 2.0)
274 | let y = floor((bounds.height - size.height) / 2.0)
275 | let origin = CGPoint(x: x, y: y)
276 |
277 | let frame = CGRect(origin: origin, size: size)
278 | label.frame = frame
279 | selectedLabel.frame = frame
280 | }
281 | }
282 | }
283 |
284 | // MARK: - UIGestureRecognizerDelegate
285 |
286 | extension EASegments: UIGestureRecognizerDelegate {
287 |
288 | override open func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
289 | if gestureRecognizer == panGesture {
290 | return selectedBackgroundView.frame.contains(gestureRecognizer.location(in: self))
291 | }
292 | return super.gestureRecognizerShouldBegin(gestureRecognizer)
293 | }
294 | }
295 |
296 | extension EASegments {
297 |
298 | public struct Appearance: Equatable {
299 | public var backgroundColor: UIColor
300 | public var selectedBackgroundColor: UIColor
301 |
302 | public var titleColor: UIColor
303 | public var selectedTitleColor: UIColor
304 |
305 | public var font: UIFont
306 |
307 | public init(backgroundColor: UIColor,
308 | selected selectedBackgroundColor: UIColor,
309 | titleColor: UIColor,
310 | selected selectedTitleColor: UIColor,
311 | font: UIFont) {
312 | self.backgroundColor = backgroundColor
313 | self.selectedBackgroundColor = selectedBackgroundColor
314 | self.titleColor = titleColor
315 | self.selectedTitleColor = selectedTitleColor
316 | self.font = font
317 | }
318 |
319 | private static let defaultFont: UIFont = UIFont.systemFont(ofSize: 16)
320 | private static let defaultBackground: UIColor = #colorLiteral(red: 0.92, green: 0.38, blue: 0.25, alpha: 1.00)
321 | private static let defaultForeground: UIColor = UIColor.white
322 |
323 | public static var `default`: Appearance = {
324 | return Appearance.init(backgroundColor: Appearance.defaultBackground,
325 | selected: Appearance.defaultForeground,
326 | titleColor: Appearance.defaultForeground,
327 | selected: Appearance.defaultBackground,
328 | font: Appearance.defaultFont)
329 | }()
330 | }
331 |
332 | public convenience init(titles: [String],
333 | delegate: EASegmentsDelegate?,
334 | appearance: Appearance = .default) {
335 | self.init(titles: titles)
336 | self.delegate = delegate
337 | self.backgroundColor = appearance.backgroundColor
338 | self.selectedBackgroundColor = appearance.selectedBackgroundColor
339 | self.titleColor = appearance.titleColor
340 | self.selectedTitleColor = appearance.selectedTitleColor
341 | self.titleFont = appearance.font
342 | }
343 | }
344 |
--------------------------------------------------------------------------------
/Sample/Sample.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 50;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 5EF09704B20290FC0AC4DEE7 /* Pods_All_Sample.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C566E79E94007910C92519D0 /* Pods_All_Sample.framework */; };
11 | 6436918920C67AF6006499AB /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6436918820C67AF6006499AB /* AppDelegate.swift */; };
12 | 6436918B20C67AF6006499AB /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6436918A20C67AF6006499AB /* ViewController.swift */; };
13 | 6436918E20C67AF6006499AB /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6436918C20C67AF6006499AB /* Main.storyboard */; };
14 | 6436919020C67AF7006499AB /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6436918F20C67AF7006499AB /* Assets.xcassets */; };
15 | 6436919320C67AF7006499AB /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6436919120C67AF7006499AB /* LaunchScreen.storyboard */; };
16 | 6436919B20C67D6C006499AB /* EASegments.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6436919A20C67D6C006499AB /* EASegments.framework */; };
17 | /* End PBXBuildFile section */
18 |
19 | /* Begin PBXFileReference section */
20 | 336B470A45B5C76E0C323000 /* Pods-All-Sample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-All-Sample.release.xcconfig"; path = "Pods/Target Support Files/Pods-All-Sample/Pods-All-Sample.release.xcconfig"; sourceTree = ""; };
21 | 49BE3E71B002D336A59DE8B9 /* Pods-All-Sample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-All-Sample.debug.xcconfig"; path = "Pods/Target Support Files/Pods-All-Sample/Pods-All-Sample.debug.xcconfig"; sourceTree = ""; };
22 | 6436918520C67AF6006499AB /* Sample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Sample.app; sourceTree = BUILT_PRODUCTS_DIR; };
23 | 6436918820C67AF6006499AB /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
24 | 6436918A20C67AF6006499AB /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; };
25 | 6436918D20C67AF6006499AB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
26 | 6436918F20C67AF7006499AB /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
27 | 6436919220C67AF7006499AB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
28 | 6436919420C67AF7006499AB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
29 | 6436919A20C67D6C006499AB /* EASegments.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = EASegments.framework; sourceTree = BUILT_PRODUCTS_DIR; };
30 | C566E79E94007910C92519D0 /* Pods_All_Sample.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_All_Sample.framework; sourceTree = BUILT_PRODUCTS_DIR; };
31 | /* End PBXFileReference section */
32 |
33 | /* Begin PBXFrameworksBuildPhase section */
34 | 6436918220C67AF6006499AB /* Frameworks */ = {
35 | isa = PBXFrameworksBuildPhase;
36 | buildActionMask = 2147483647;
37 | files = (
38 | 6436919B20C67D6C006499AB /* EASegments.framework in Frameworks */,
39 | 5EF09704B20290FC0AC4DEE7 /* Pods_All_Sample.framework in Frameworks */,
40 | );
41 | runOnlyForDeploymentPostprocessing = 0;
42 | };
43 | /* End PBXFrameworksBuildPhase section */
44 |
45 | /* Begin PBXGroup section */
46 | 04D2CE1B4DD14B3A0354B2E9 /* Pods */ = {
47 | isa = PBXGroup;
48 | children = (
49 | 49BE3E71B002D336A59DE8B9 /* Pods-All-Sample.debug.xcconfig */,
50 | 336B470A45B5C76E0C323000 /* Pods-All-Sample.release.xcconfig */,
51 | );
52 | name = Pods;
53 | sourceTree = "";
54 | };
55 | 6436917C20C67AF6006499AB = {
56 | isa = PBXGroup;
57 | children = (
58 | 6436918720C67AF6006499AB /* Sample */,
59 | 6436918620C67AF6006499AB /* Products */,
60 | 04D2CE1B4DD14B3A0354B2E9 /* Pods */,
61 | AFC60B9F0D1F1D95BEB66023 /* Frameworks */,
62 | );
63 | sourceTree = "";
64 | };
65 | 6436918620C67AF6006499AB /* Products */ = {
66 | isa = PBXGroup;
67 | children = (
68 | 6436918520C67AF6006499AB /* Sample.app */,
69 | );
70 | name = Products;
71 | sourceTree = "";
72 | };
73 | 6436918720C67AF6006499AB /* Sample */ = {
74 | isa = PBXGroup;
75 | children = (
76 | 6436918820C67AF6006499AB /* AppDelegate.swift */,
77 | 6436918A20C67AF6006499AB /* ViewController.swift */,
78 | 6436918C20C67AF6006499AB /* Main.storyboard */,
79 | 6436918F20C67AF7006499AB /* Assets.xcassets */,
80 | 6436919120C67AF7006499AB /* LaunchScreen.storyboard */,
81 | 6436919420C67AF7006499AB /* Info.plist */,
82 | );
83 | path = Sample;
84 | sourceTree = "";
85 | };
86 | AFC60B9F0D1F1D95BEB66023 /* Frameworks */ = {
87 | isa = PBXGroup;
88 | children = (
89 | 6436919A20C67D6C006499AB /* EASegments.framework */,
90 | C566E79E94007910C92519D0 /* Pods_All_Sample.framework */,
91 | );
92 | name = Frameworks;
93 | sourceTree = "";
94 | };
95 | /* End PBXGroup section */
96 |
97 | /* Begin PBXNativeTarget section */
98 | 6436918420C67AF6006499AB /* Sample */ = {
99 | isa = PBXNativeTarget;
100 | buildConfigurationList = 6436919720C67AF7006499AB /* Build configuration list for PBXNativeTarget "Sample" */;
101 | buildPhases = (
102 | BE0C22AE3DC23504EACA007E /* [CP] Check Pods Manifest.lock */,
103 | 6436918120C67AF6006499AB /* Sources */,
104 | 6436918220C67AF6006499AB /* Frameworks */,
105 | 6436918320C67AF6006499AB /* Resources */,
106 | DE0FA35AF5A63A49238CBE90 /* [CP] Embed Pods Frameworks */,
107 | );
108 | buildRules = (
109 | );
110 | dependencies = (
111 | );
112 | name = Sample;
113 | productName = Sample;
114 | productReference = 6436918520C67AF6006499AB /* Sample.app */;
115 | productType = "com.apple.product-type.application";
116 | };
117 | /* End PBXNativeTarget section */
118 |
119 | /* Begin PBXProject section */
120 | 6436917D20C67AF6006499AB /* Project object */ = {
121 | isa = PBXProject;
122 | attributes = {
123 | LastSwiftUpdateCheck = 0940;
124 | LastUpgradeCheck = 0940;
125 | ORGANIZATIONNAME = "Meniny Lab";
126 | TargetAttributes = {
127 | 6436918420C67AF6006499AB = {
128 | CreatedOnToolsVersion = 9.4;
129 | };
130 | };
131 | };
132 | buildConfigurationList = 6436918020C67AF6006499AB /* Build configuration list for PBXProject "Sample" */;
133 | compatibilityVersion = "Xcode 9.3";
134 | developmentRegion = en;
135 | hasScannedForEncodings = 0;
136 | knownRegions = (
137 | en,
138 | Base,
139 | );
140 | mainGroup = 6436917C20C67AF6006499AB;
141 | productRefGroup = 6436918620C67AF6006499AB /* Products */;
142 | projectDirPath = "";
143 | projectRoot = "";
144 | targets = (
145 | 6436918420C67AF6006499AB /* Sample */,
146 | );
147 | };
148 | /* End PBXProject section */
149 |
150 | /* Begin PBXResourcesBuildPhase section */
151 | 6436918320C67AF6006499AB /* Resources */ = {
152 | isa = PBXResourcesBuildPhase;
153 | buildActionMask = 2147483647;
154 | files = (
155 | 6436919320C67AF7006499AB /* LaunchScreen.storyboard in Resources */,
156 | 6436919020C67AF7006499AB /* Assets.xcassets in Resources */,
157 | 6436918E20C67AF6006499AB /* Main.storyboard in Resources */,
158 | );
159 | runOnlyForDeploymentPostprocessing = 0;
160 | };
161 | /* End PBXResourcesBuildPhase section */
162 |
163 | /* Begin PBXShellScriptBuildPhase section */
164 | BE0C22AE3DC23504EACA007E /* [CP] Check Pods Manifest.lock */ = {
165 | isa = PBXShellScriptBuildPhase;
166 | buildActionMask = 2147483647;
167 | files = (
168 | );
169 | inputPaths = (
170 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
171 | "${PODS_ROOT}/Manifest.lock",
172 | );
173 | name = "[CP] Check Pods Manifest.lock";
174 | outputPaths = (
175 | "$(DERIVED_FILE_DIR)/Pods-All-Sample-checkManifestLockResult.txt",
176 | );
177 | runOnlyForDeploymentPostprocessing = 0;
178 | shellPath = /bin/sh;
179 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
180 | showEnvVarsInLog = 0;
181 | };
182 | DE0FA35AF5A63A49238CBE90 /* [CP] Embed Pods Frameworks */ = {
183 | isa = PBXShellScriptBuildPhase;
184 | buildActionMask = 2147483647;
185 | files = (
186 | );
187 | inputPaths = (
188 | "${SRCROOT}/Pods/Target Support Files/Pods-All-Sample/Pods-All-Sample-frameworks.sh",
189 | "${BUILT_PRODUCTS_DIR}/EASegments/EASegments.framework",
190 | );
191 | name = "[CP] Embed Pods Frameworks";
192 | outputPaths = (
193 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/EASegments.framework",
194 | );
195 | runOnlyForDeploymentPostprocessing = 0;
196 | shellPath = /bin/sh;
197 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-All-Sample/Pods-All-Sample-frameworks.sh\"\n";
198 | showEnvVarsInLog = 0;
199 | };
200 | /* End PBXShellScriptBuildPhase section */
201 |
202 | /* Begin PBXSourcesBuildPhase section */
203 | 6436918120C67AF6006499AB /* Sources */ = {
204 | isa = PBXSourcesBuildPhase;
205 | buildActionMask = 2147483647;
206 | files = (
207 | 6436918B20C67AF6006499AB /* ViewController.swift in Sources */,
208 | 6436918920C67AF6006499AB /* AppDelegate.swift in Sources */,
209 | );
210 | runOnlyForDeploymentPostprocessing = 0;
211 | };
212 | /* End PBXSourcesBuildPhase section */
213 |
214 | /* Begin PBXVariantGroup section */
215 | 6436918C20C67AF6006499AB /* Main.storyboard */ = {
216 | isa = PBXVariantGroup;
217 | children = (
218 | 6436918D20C67AF6006499AB /* Base */,
219 | );
220 | name = Main.storyboard;
221 | sourceTree = "";
222 | };
223 | 6436919120C67AF7006499AB /* LaunchScreen.storyboard */ = {
224 | isa = PBXVariantGroup;
225 | children = (
226 | 6436919220C67AF7006499AB /* Base */,
227 | );
228 | name = LaunchScreen.storyboard;
229 | sourceTree = "";
230 | };
231 | /* End PBXVariantGroup section */
232 |
233 | /* Begin XCBuildConfiguration section */
234 | 6436919520C67AF7006499AB /* Debug */ = {
235 | isa = XCBuildConfiguration;
236 | buildSettings = {
237 | ALWAYS_SEARCH_USER_PATHS = NO;
238 | CLANG_ANALYZER_NONNULL = YES;
239 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
240 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
241 | CLANG_CXX_LIBRARY = "libc++";
242 | CLANG_ENABLE_MODULES = YES;
243 | CLANG_ENABLE_OBJC_ARC = YES;
244 | CLANG_ENABLE_OBJC_WEAK = YES;
245 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
246 | CLANG_WARN_BOOL_CONVERSION = YES;
247 | CLANG_WARN_COMMA = YES;
248 | CLANG_WARN_CONSTANT_CONVERSION = YES;
249 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
250 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
251 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
252 | CLANG_WARN_EMPTY_BODY = YES;
253 | CLANG_WARN_ENUM_CONVERSION = YES;
254 | CLANG_WARN_INFINITE_RECURSION = YES;
255 | CLANG_WARN_INT_CONVERSION = YES;
256 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
257 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
258 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
259 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
260 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
261 | CLANG_WARN_STRICT_PROTOTYPES = YES;
262 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
263 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
264 | CLANG_WARN_UNREACHABLE_CODE = YES;
265 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
266 | CODE_SIGN_IDENTITY = "iPhone Developer";
267 | COPY_PHASE_STRIP = NO;
268 | DEBUG_INFORMATION_FORMAT = dwarf;
269 | ENABLE_STRICT_OBJC_MSGSEND = YES;
270 | ENABLE_TESTABILITY = YES;
271 | GCC_C_LANGUAGE_STANDARD = gnu11;
272 | GCC_DYNAMIC_NO_PIC = NO;
273 | GCC_NO_COMMON_BLOCKS = YES;
274 | GCC_OPTIMIZATION_LEVEL = 0;
275 | GCC_PREPROCESSOR_DEFINITIONS = (
276 | "DEBUG=1",
277 | "$(inherited)",
278 | );
279 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
280 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
281 | GCC_WARN_UNDECLARED_SELECTOR = YES;
282 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
283 | GCC_WARN_UNUSED_FUNCTION = YES;
284 | GCC_WARN_UNUSED_VARIABLE = YES;
285 | IPHONEOS_DEPLOYMENT_TARGET = 11.4;
286 | MTL_ENABLE_DEBUG_INFO = YES;
287 | ONLY_ACTIVE_ARCH = YES;
288 | SDKROOT = iphoneos;
289 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
290 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
291 | };
292 | name = Debug;
293 | };
294 | 6436919620C67AF7006499AB /* Release */ = {
295 | isa = XCBuildConfiguration;
296 | buildSettings = {
297 | ALWAYS_SEARCH_USER_PATHS = NO;
298 | CLANG_ANALYZER_NONNULL = YES;
299 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
300 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
301 | CLANG_CXX_LIBRARY = "libc++";
302 | CLANG_ENABLE_MODULES = YES;
303 | CLANG_ENABLE_OBJC_ARC = YES;
304 | CLANG_ENABLE_OBJC_WEAK = YES;
305 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
306 | CLANG_WARN_BOOL_CONVERSION = YES;
307 | CLANG_WARN_COMMA = YES;
308 | CLANG_WARN_CONSTANT_CONVERSION = YES;
309 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
310 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
311 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
312 | CLANG_WARN_EMPTY_BODY = YES;
313 | CLANG_WARN_ENUM_CONVERSION = YES;
314 | CLANG_WARN_INFINITE_RECURSION = YES;
315 | CLANG_WARN_INT_CONVERSION = YES;
316 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
317 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
318 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
319 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
320 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
321 | CLANG_WARN_STRICT_PROTOTYPES = YES;
322 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
323 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
324 | CLANG_WARN_UNREACHABLE_CODE = YES;
325 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
326 | CODE_SIGN_IDENTITY = "iPhone Developer";
327 | COPY_PHASE_STRIP = NO;
328 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
329 | ENABLE_NS_ASSERTIONS = NO;
330 | ENABLE_STRICT_OBJC_MSGSEND = YES;
331 | GCC_C_LANGUAGE_STANDARD = gnu11;
332 | GCC_NO_COMMON_BLOCKS = YES;
333 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
334 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
335 | GCC_WARN_UNDECLARED_SELECTOR = YES;
336 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
337 | GCC_WARN_UNUSED_FUNCTION = YES;
338 | GCC_WARN_UNUSED_VARIABLE = YES;
339 | IPHONEOS_DEPLOYMENT_TARGET = 11.4;
340 | MTL_ENABLE_DEBUG_INFO = NO;
341 | SDKROOT = iphoneos;
342 | SWIFT_COMPILATION_MODE = wholemodule;
343 | SWIFT_OPTIMIZATION_LEVEL = "-O";
344 | VALIDATE_PRODUCT = YES;
345 | };
346 | name = Release;
347 | };
348 | 6436919820C67AF7006499AB /* Debug */ = {
349 | isa = XCBuildConfiguration;
350 | baseConfigurationReference = 49BE3E71B002D336A59DE8B9 /* Pods-All-Sample.debug.xcconfig */;
351 | buildSettings = {
352 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
353 | CODE_SIGN_STYLE = Automatic;
354 | DEVELOPMENT_TEAM = 63YL5QDMNS;
355 | INFOPLIST_FILE = Sample/Info.plist;
356 | LD_RUNPATH_SEARCH_PATHS = (
357 | "$(inherited)",
358 | "@executable_path/Frameworks",
359 | );
360 | PRODUCT_BUNDLE_IDENTIFIER = cn.meniny.EASegments.Sample;
361 | PRODUCT_NAME = "$(TARGET_NAME)";
362 | SWIFT_VERSION = 4.0;
363 | TARGETED_DEVICE_FAMILY = "1,2";
364 | };
365 | name = Debug;
366 | };
367 | 6436919920C67AF7006499AB /* Release */ = {
368 | isa = XCBuildConfiguration;
369 | baseConfigurationReference = 336B470A45B5C76E0C323000 /* Pods-All-Sample.release.xcconfig */;
370 | buildSettings = {
371 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
372 | CODE_SIGN_STYLE = Automatic;
373 | DEVELOPMENT_TEAM = 63YL5QDMNS;
374 | INFOPLIST_FILE = Sample/Info.plist;
375 | LD_RUNPATH_SEARCH_PATHS = (
376 | "$(inherited)",
377 | "@executable_path/Frameworks",
378 | );
379 | PRODUCT_BUNDLE_IDENTIFIER = cn.meniny.EASegments.Sample;
380 | PRODUCT_NAME = "$(TARGET_NAME)";
381 | SWIFT_VERSION = 4.0;
382 | TARGETED_DEVICE_FAMILY = "1,2";
383 | };
384 | name = Release;
385 | };
386 | /* End XCBuildConfiguration section */
387 |
388 | /* Begin XCConfigurationList section */
389 | 6436918020C67AF6006499AB /* Build configuration list for PBXProject "Sample" */ = {
390 | isa = XCConfigurationList;
391 | buildConfigurations = (
392 | 6436919520C67AF7006499AB /* Debug */,
393 | 6436919620C67AF7006499AB /* Release */,
394 | );
395 | defaultConfigurationIsVisible = 0;
396 | defaultConfigurationName = Release;
397 | };
398 | 6436919720C67AF7006499AB /* Build configuration list for PBXNativeTarget "Sample" */ = {
399 | isa = XCConfigurationList;
400 | buildConfigurations = (
401 | 6436919820C67AF7006499AB /* Debug */,
402 | 6436919920C67AF7006499AB /* Release */,
403 | );
404 | defaultConfigurationIsVisible = 0;
405 | defaultConfigurationName = Release;
406 | };
407 | /* End XCConfigurationList section */
408 | };
409 | rootObject = 6436917D20C67AF6006499AB /* Project object */;
410 | }
411 |
--------------------------------------------------------------------------------