18 |
19 |
20 |
--------------------------------------------------------------------------------
/EMSpinnerButtonTests/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 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/EMSpinnerButton/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 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | $(CURRENT_PROJECT_VERSION)
21 | NSPrincipalClass
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Eduardo Moll
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 |
--------------------------------------------------------------------------------
/EMSpinnerButtonTests/EMSpinnerButtonTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // EMSpinnerButtonTests.swift
3 | // EMSpinnerButtonTests
4 | //
5 | // Created by Eduardo Moll on 11/25/17.
6 | // Copyright © 2017 Eduardo Moll. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | @testable import EMSpinnerButton
11 |
12 | class EMSpinnerButtonTests: XCTestCase {
13 |
14 | var button: EMSpinnerButton!
15 |
16 | override func setUp() {
17 | super.setUp()
18 | button = EMSpinnerButton(title: "Login")
19 | button!.frame = CGRect(x: 0, y: 0, width: 200, height: 40)
20 | }
21 |
22 | override func tearDown() {
23 | super.tearDown()
24 | button = nil
25 | }
26 |
27 | // MARK: - Title Tests
28 | func testTitle() {
29 | button.title = "LOGIN"
30 | XCTAssertEqual(button.title, "LOGIN", "Button title is not correct")
31 | }
32 |
33 | func testTitleAfterCollapse() {
34 | button.animate(animation: .collapse)
35 | XCTAssertEqual(button.title, "Login", "Button title after collapse is not correct")
36 | }
37 |
38 | func testTitleAfterExpand() {
39 | button.title = "LOGIN"
40 | button.animate(animation: .collapse)
41 | button.animate(animation: .expand)
42 | XCTAssertEqual(button.title, "LOGIN", "Button title after expand is not correct")
43 | }
44 |
45 | // MARK: - Frame Tests
46 | func testCenterAfterShake() {
47 | let centerBeforeShake = button.center
48 | button.animate(animation: .shake)
49 | XCTAssertEqual(button.center, centerBeforeShake, "Button center after shake animation is not correct")
50 | }
51 |
52 | func testGradientColor() {
53 | let colors: [CGColor] = [UIColor.lightGray.cgColor, UIColor.darkGray.cgColor]
54 | button.gradientColors = colors
55 | XCTAssertEqual(button.gradientLayer.colors as! [CGColor], colors, "Gradient Colors are not equal")
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/EMSpinnerButton/EMSpinnerButton/EMSpinnerLayer.swift:
--------------------------------------------------------------------------------
1 | //
2 | // EMLoadingIndicatorLayer.swift
3 | // ButtonAnimation
4 | //
5 | // Created by Eduardo Moll on 11/22/17.
6 | // Copyright © 2017 Eduardo Moll. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | internal class EMSpinnerLayer: CAShapeLayer {
12 |
13 | internal var color: CGColor? = UIColor.white.cgColor {
14 | willSet {
15 | strokeColor = newValue
16 | }
17 | }
18 |
19 | required init?(coder aDecoder: NSCoder) {
20 | super.init(coder: aDecoder)
21 | }
22 |
23 | init(frame: CGRect) {
24 | super.init()
25 | setUp(frame: frame)
26 | }
27 | }
28 |
29 | // MARK: - Setup
30 | internal extension EMSpinnerLayer {
31 |
32 | func setUp(frame: CGRect) {
33 | self.frame = CGRect(x: 0, y: 0, width: frame.height, height: frame.height)
34 | let center = CGPoint(x: frame.height/2, y: frame.height/2)
35 |
36 | let circlePath = UIBezierPath(arcCenter: center, radius: 10, startAngle: 0, endAngle: CGFloat(2*Double.pi), clockwise: true)
37 |
38 | path = circlePath.cgPath
39 | lineWidth = 2.0
40 | strokeColor = color
41 | fillColor = UIColor.clear.cgColor
42 |
43 | self.isHidden = true
44 | }
45 | }
46 |
47 | // MARK: - Animation Methods
48 | internal extension EMSpinnerLayer {
49 |
50 | func startAnimation() {
51 | let strokeStartAnimation = CABasicAnimation(keyPath: "strokeStart")
52 | strokeStartAnimation.fromValue = -0.5
53 | strokeStartAnimation.toValue = 1.0
54 |
55 | let strokeEndAnimation = CABasicAnimation(keyPath: "strokeEnd")
56 | strokeEndAnimation.fromValue = 0.0
57 | strokeEndAnimation.toValue = 1.0
58 |
59 | let animationGroup = CAAnimationGroup()
60 | animationGroup.duration = 1
61 | animationGroup.repeatCount = .infinity
62 | animationGroup.animations = [strokeStartAnimation, strokeEndAnimation]
63 |
64 | add(animationGroup, forKey: nil)
65 | }
66 |
67 | func stopAnimation() {
68 | removeAllAnimations()
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/Readme.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | []()
6 | []()
7 | []()
8 | [](https://github.com/egmoll7/EMSpinnerButton/stargazers)
9 | []()
10 |
11 |
12 | EMSpinnerButton is an elegant button with a spinner animation and is fully customizable.
13 | Inspired by the Starbucks app
14 |
15 |
16 |
17 |
18 |
19 | ## Table of Contents
20 | * [Features](#features)
21 | * [Requirements](#requirements)
22 | * [Installation](#installation)
23 | * [Usage](#usage)
24 | * [Customization](#customization)
25 | * [Title](#button-title)
26 | * [Corner Radius](#corner-radius)
27 | * [Title Color](#title-color)
28 | * [Background Color](#background-color)
29 | * [Background Gradient Color](#background-gradient-color)
30 | * [Spinner Color](#spinner-color)
31 | * [License](#license)
32 |
33 | ## Features
34 | * [x] Title
35 | * [x] Gradient Background (Optional)
36 | * [x] Various animations
37 | * [x] Fully Customizable
38 | * [x] CocoaPods
39 |
40 | ## Requirements
41 | * iOS 9.0+
42 | * Xcode 9+
43 |
44 | ## Installation
45 | [CocoaPods](http://cocoapods.org) is a dependency manager for Cocoa projects. You can install it with the following command:
46 |
47 | ```bash
48 | $ gem install cocoapods
49 | ```
50 |
51 | To integrate EMSpinnerButton into your Xcode project using CocoaPods, specify it in your Podfile:
52 |
53 | ```ruby
54 | source 'https://github.com/CocoaPods/Specs.git'
55 | platform :ios, '9.0'
56 | use_frameworks!
57 |
58 | target '' do
59 | pod 'EMSpinnerButton'
60 | end
61 | ```
62 |
63 | Then, run the following command:
64 |
65 | ```bash
66 | $ pod install
67 | ```
68 |
69 | ## Usage
70 | In the storyboard add a UIButton and change its class to EMSpinnerButton
71 |
72 | ### Animations
73 |
74 | ### Collapse
75 | ```swift
76 | // Collapse animation
77 | button.animate(animation: .collapse)
78 | ```
79 | ----------------
80 |
81 | ### Expand
82 | ```swift
83 | // Expand animation
84 | button.animate(animation: .expand)
85 | ```
86 | ----------------
87 |
88 | ### Shake
89 | ```swift
90 | // Shake animation
91 | button.animate(animation: .shake)
92 | ```
93 |
94 | ## Customization
95 |
96 | ### Button Title
97 | ```swift
98 | button.title = "LOGIN"
99 | // Default title = nil
100 | ```
101 |
102 | ### Corner Radius
103 | ```swift
104 | button.cornerRadius = button.frame.height/2
105 | // Default corner radius = 0
106 | ```
107 |
108 | ### Title Color
109 | ```swift
110 | button.titleColor = UIColor.red
111 | // Default color = UIColor.white
112 | ```
113 |
114 | ### Background Color
115 | ```swift
116 | button.backgroundColor = UIColor.white
117 | // Default color = UIColor(red: 49/255, green: 177/255, blue: 229/255, alpha: 1.0)
118 | ```
119 |
120 | ### Background Gradient Color
121 | ```swift
122 | button.gradientColor = UIColor.white
123 | // Default colors = nil
124 | ```
125 |
126 | ### Spinner Color
127 | ```swift
128 | button.spinnerColor = UIColor.lightGray.cgColor
129 | // Default color = UIColor.white.cgColor
130 | ```
131 |
132 | ## License
133 | ----------------
134 | EMSpinnerButton is available under the MIT license. See the LICENSE file for more info.
135 |
--------------------------------------------------------------------------------
/EMSpinnerButton.podspec:
--------------------------------------------------------------------------------
1 | #
2 | # Be sure to run `pod spec lint EMSpinnerButton.podspec' to ensure this is a
3 | # valid spec and to remove all comments including this before submitting the spec.
4 | #
5 | # To learn more about Podspec attributes see http://docs.cocoapods.org/specification.html
6 | # To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/
7 | #
8 |
9 | Pod::Spec.new do |s|
10 |
11 | # ――― Spec Metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
12 | #
13 | # These will help people to find your library, and whilst it
14 | # can feel like a chore to fill in it's definitely to your advantage. The
15 | # summary should be tweet-length, and the description more in depth.
16 | #
17 |
18 | s.name = "EMSpinnerButton"
19 | s.version = "1.0.1"
20 | s.summary = "EMSpinnerButton is an elegant button with a spinner animation."
21 |
22 | # This description is used to generate tags and improve search results.
23 | # * Think: What does it do? Why did you write it? What is the focus?
24 | # * Try to keep it short, snappy and to the point.
25 | # * Write the description between the DESC delimiters below.
26 | # * Finally, don't worry about the indent, CocoaPods strips it!
27 | s.description = <<-DESC
28 | EMSpinnerButton is an elegant button with a spinner animation and is fully customizable.
29 | Inspired by the Starbucks app
30 | DESC
31 |
32 | s.homepage = "https://github.com/egmoll7/EMSpinnerButton"
33 | # s.screenshots = "www.example.com/screenshots_1.gif", "www.example.com/screenshots_2.gif"
34 |
35 |
36 | # ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
37 | #
38 | # Licensing your code is important. See http://choosealicense.com for more info.
39 | # CocoaPods will detect a license file if there is a named LICENSE*
40 | # Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'.
41 | #
42 |
43 | s.license = { :type => 'MIT', :file => 'LICENSE' }
44 |
45 |
46 | # ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
47 | #
48 | # Specify the authors of the library, with email addresses. Email addresses
49 | # of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also
50 | # accepts just a name if you'd rather not provide an email address.
51 | #
52 | # Specify a social_media_url where others can refer to, for example a twitter
53 | # profile URL.
54 | #
55 |
56 | s.author = { "egmoll7" => "egmoll7@gmail.com" }
57 | s.social_media_url = "http://twitter.com/egmoll7"
58 |
59 | # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
60 | #
61 | # If this Pod runs only on iOS or OS X, then specify the platform and
62 | # the deployment target. You can optionally include the target after the platform.
63 | #
64 | s.ios.deployment_target = "9.0"
65 |
66 |
67 |
68 | # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
69 | #
70 | # Specify the location from where the source should be retrieved.
71 | # Supports git, hg, bzr, svn and HTTP.
72 | #
73 |
74 | s.source = { :git => "http://github.com/egmoll7/EMSpinnerButton.git", :tag => "#{s.version}" }
75 |
76 |
77 | # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
78 | #
79 | # CocoaPods is smart about how it includes source code. For source files
80 | # giving a folder will include any swift, h, m, mm, c & cpp files.
81 | # For header files it will include any header in the folder.
82 | # Not including the public_header_files will make all headers public.
83 | #
84 |
85 | s.source_files = "EMSpinnerButton", "EMSpinnerButton/**/*.{h,m,swift}"
86 | s.exclude_files = "Classes/Exclude"
87 |
88 | # s.public_header_files = "Classes/**/*.h"
89 |
90 |
91 | # ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
92 | #
93 | # A list of resources included with the Pod. These are copied into the
94 | # target bundle with a build phase script. Anything else will be cleaned.
95 | # You can preserve files from being cleaned, please don't preserve
96 | # non-essential files like tests, examples and documentation.
97 | #
98 |
99 | # s.resource = "icon.png"
100 | # s.resources = "Resources/*.png"
101 |
102 | # s.preserve_paths = "FilesToSave", "MoreFilesToSave"
103 |
104 | # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― #
105 | #
106 | # If your library depends on compiler flags you can set them in the xcconfig hash
107 | # where they will only apply to your library. If you depend on other Podspecs
108 | # you can include multiple dependencies to ensure it works.
109 | s.pod_target_xcconfig = { 'SWIFT_VERSION' => '4' }
110 |
111 | end
112 |
--------------------------------------------------------------------------------
/EMSpinnerButton/EMSpinnerButton/EMSpinnerButton.swift:
--------------------------------------------------------------------------------
1 | //
2 | // EMLoadingButton.swift
3 | // ButtonAnimation
4 | //
5 | // Created by Eduardo Moll on 11/22/17.
6 | // Copyright © 2017 Eduardo Moll. All rights reserved.
7 | //
8 |
9 |
10 | import UIKit
11 |
12 | public enum AnimationType {
13 |
14 | /// Collapse animation will make the button round and show the spinner
15 | case collapse
16 | /// Expand animation will make the button go back to the defaults, use after button is "collapsed"
17 | case expand
18 | /// Shake animation will shake the button
19 | case shake
20 | }
21 |
22 | extension CAGradientLayer {
23 | convenience init(frame: CGRect) {
24 | self.init()
25 | self.frame = frame
26 | }
27 | }
28 |
29 | @IBDesignable
30 | open class EMSpinnerButton: UIButton {
31 | // MARK: - Properties
32 | internal var storedTitle: String?
33 | internal var animationDuration: CFTimeInterval = 0.1
34 |
35 | /// Sets the button corner radius
36 | @IBInspectable public var cornerRadius: CGFloat = 0 {
37 | willSet {
38 | layer.cornerRadius = newValue
39 | }
40 | }
41 |
42 | /// Sets the duration of the animations
43 | @IBInspectable public var duration: Double = 0.2 {
44 | willSet {
45 | animationDuration = newValue
46 | }
47 | }
48 |
49 | internal lazy var spinner: EMSpinnerLayer = {
50 | let spiner = EMSpinnerLayer(frame: self.frame)
51 | self.layer.addSublayer(spiner)
52 | return spiner
53 | }()
54 |
55 | internal lazy var gradientLayer: CAGradientLayer = {
56 | let gradient = CAGradientLayer(frame: self.frame)
57 | gradient.startPoint = CGPoint(x: 0.0, y: 0.0)
58 | gradient.endPoint = CGPoint(x: 1.0, y: 1.0)
59 | layer.insertSublayer(gradient, at: 0)
60 | return gradient
61 | }()
62 |
63 | /// Sets the spinner color
64 | public var spinnerColor: CGColor? {
65 | willSet {
66 | spinner.color = newValue
67 | }
68 | }
69 |
70 | /// Sets the colors for the gradient backgorund
71 | public var gradientColors: [CGColor]? {
72 | willSet {
73 | gradientLayer.colors = newValue
74 | }
75 | }
76 |
77 | /// Sets the button title for its normal state
78 | public var title: String? {
79 | get {
80 | return self.title(for: .normal)
81 | }
82 | set {
83 | self.setTitle(newValue, for: .normal)
84 | }
85 | }
86 |
87 | /// Sets the button title color.
88 | public var titleColor: UIColor? {
89 | get {
90 | return self.titleColor(for: .normal)
91 | }
92 | set {
93 | self.setTitleColor(newValue, for: .normal)
94 | }
95 | }
96 |
97 | // MARK: - Initializers
98 | public required init(coder aDecoder: NSCoder) {
99 | super.init(coder: aDecoder)!
100 | setUp()
101 | }
102 |
103 | public override init(frame: CGRect) {
104 | super.init(frame: frame)
105 | setUp()
106 | }
107 |
108 | public init(title: String) {
109 | super.init(frame: .zero)
110 | setTitle(title, for: .normal)
111 | setUp()
112 | }
113 |
114 | open override func layoutSubviews() {
115 | super.layoutSubviews()
116 | gradientLayer.frame = self.bounds
117 | clipsToBounds = true
118 | }
119 | }
120 |
121 | internal extension EMSpinnerButton {
122 | internal func setUp() {
123 | self.titleLabel?.font = UIFont.systemFont(ofSize: 15, weight: .medium)
124 | self.backgroundColor = .emLightBlue
125 | self.titleColor = .white
126 | }
127 | }
128 |
129 | // MARK: - Animation Methods
130 | internal extension EMSpinnerButton {
131 |
132 | internal func collapseAnimation() {
133 | storedTitle = title
134 | title = ""
135 | isUserInteractionEnabled = false
136 |
137 | let animaton = CABasicAnimation(keyPath: "bounds.size.width")
138 | animaton.fromValue = frame.width
139 | animaton.toValue = frame.height
140 | animaton.duration = animationDuration
141 | animaton.fillMode = CAMediaTimingFillMode.forwards
142 | animaton.isRemovedOnCompletion = false
143 |
144 | layer.add(animaton, forKey: animaton.keyPath)
145 | spinner.isHidden = false
146 | spinner.startAnimation()
147 | }
148 |
149 | internal func backToDefaults() {
150 |
151 | spinner.stopAnimation()
152 | setTitle(storedTitle, for: .normal)
153 | isUserInteractionEnabled = true
154 |
155 | let animaton = CABasicAnimation(keyPath: "bounds.size.width")
156 | animaton.fromValue = frame.height
157 | animaton.toValue = frame.width
158 | animaton.duration = animationDuration
159 | animaton.fillMode = CAMediaTimingFillMode.forwards
160 | animaton.isRemovedOnCompletion = false
161 |
162 | layer.add(animaton, forKey: animaton.keyPath)
163 | spinner.isHidden = true
164 | }
165 |
166 | internal func shakeAnimation() {
167 |
168 | UIView.animateKeyframes(withDuration: 0.5, delay: 0, options: [], animations: {
169 |
170 | UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 0.1, animations: {
171 | let transform = CGAffineTransform(translationX: 10, y: 0)
172 | self.transform = transform
173 | })
174 |
175 | UIView.addKeyframe(withRelativeStartTime: 0.1, relativeDuration: 0.1, animations: {
176 | let transform = CGAffineTransform(translationX: -7, y: 0)
177 | self.transform = transform
178 | })
179 |
180 | UIView.addKeyframe(withRelativeStartTime: 0.2, relativeDuration: 0.1, animations: {
181 | let transform = CGAffineTransform(translationX: 5, y: 0)
182 | self.transform = transform
183 | })
184 |
185 | UIView.addKeyframe(withRelativeStartTime: 0.3, relativeDuration: 0.1, animations: {
186 | let transform = CGAffineTransform(translationX: -3, y: 0)
187 | self.transform = transform
188 | })
189 |
190 | UIView.addKeyframe(withRelativeStartTime: 0.4, relativeDuration: 0.1, animations: {
191 | let transform = CGAffineTransform(translationX: 2, y: 0)
192 | self.transform = transform
193 | })
194 |
195 | UIView.addKeyframe(withRelativeStartTime: 0.5, relativeDuration: 0.1, animations: {
196 | let transform = CGAffineTransform(translationX: -1, y: 0)
197 | self.transform = transform
198 | })
199 | })
200 | }
201 | }
202 |
203 | // MARK: - Public Methods
204 | public extension EMSpinnerButton {
205 |
206 | /**
207 | Animates the the button with the given animation
208 | - parameter animation: Type of animation that will be executed
209 | */
210 | public func animate(animation: AnimationType) {
211 |
212 | switch animation {
213 |
214 | case .collapse:
215 | UIView.animate(withDuration: 0.1, animations: {
216 | self.layer.cornerRadius = self.frame.height/2
217 | }, completion: { (completion) in
218 | self.collapseAnimation()
219 | })
220 |
221 | case .expand:
222 | UIView.animate(withDuration: 0.1, animations: {
223 | self.layer.cornerRadius = self.cornerRadius
224 | }, completion: { (completion) in
225 | self.backToDefaults()
226 | })
227 |
228 | case .shake:
229 | shakeAnimation()
230 | }
231 | }
232 | }
233 |
234 | // MARK: - Custom Colors
235 | internal extension UIColor {
236 |
237 | static let emLightBlue = UIColor().lightBlueColor()
238 |
239 | private func lightBlueColor() -> UIColor {
240 | return UIColor(red: 49/255, green: 177/255, blue: 229/255, alpha: 1.0)
241 | }
242 | }
243 |
244 |
--------------------------------------------------------------------------------
/EMSpinnerButton.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 48;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 8847E6361FC9A6A6004B674D /* EMSpinnerButton.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8847E62C1FC9A6A6004B674D /* EMSpinnerButton.framework */; };
11 | 8847E63B1FC9A6A6004B674D /* EMSpinnerButtonTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8847E63A1FC9A6A6004B674D /* EMSpinnerButtonTests.swift */; };
12 | 8847E63D1FC9A6A6004B674D /* EMSpinnerButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 8847E62F1FC9A6A6004B674D /* EMSpinnerButton.h */; settings = {ATTRIBUTES = (Public, ); }; };
13 | 88CB43C81FCF961E0026771C /* EMSpinnerLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88CB43C61FCF961E0026771C /* EMSpinnerLayer.swift */; };
14 | 88CB43C91FCF961E0026771C /* EMSpinnerButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88CB43C71FCF961E0026771C /* EMSpinnerButton.swift */; };
15 | /* End PBXBuildFile section */
16 |
17 | /* Begin PBXContainerItemProxy section */
18 | 8847E6371FC9A6A6004B674D /* PBXContainerItemProxy */ = {
19 | isa = PBXContainerItemProxy;
20 | containerPortal = 8847E6231FC9A6A6004B674D /* Project object */;
21 | proxyType = 1;
22 | remoteGlobalIDString = 8847E62B1FC9A6A6004B674D;
23 | remoteInfo = EMSpinnerButton;
24 | };
25 | /* End PBXContainerItemProxy section */
26 |
27 | /* Begin PBXFileReference section */
28 | 8847E62C1FC9A6A6004B674D /* EMSpinnerButton.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = EMSpinnerButton.framework; sourceTree = BUILT_PRODUCTS_DIR; };
29 | 8847E62F1FC9A6A6004B674D /* EMSpinnerButton.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EMSpinnerButton.h; sourceTree = ""; };
30 | 8847E6301FC9A6A6004B674D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
31 | 8847E6351FC9A6A6004B674D /* EMSpinnerButtonTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = EMSpinnerButtonTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
32 | 8847E63A1FC9A6A6004B674D /* EMSpinnerButtonTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EMSpinnerButtonTests.swift; sourceTree = ""; };
33 | 8847E63C1FC9A6A6004B674D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
34 | 88CB43C61FCF961E0026771C /* EMSpinnerLayer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = EMSpinnerLayer.swift; path = EMSpinnerButton/EMSpinnerButton/EMSpinnerLayer.swift; sourceTree = SOURCE_ROOT; };
35 | 88CB43C71FCF961E0026771C /* EMSpinnerButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = EMSpinnerButton.swift; path = EMSpinnerButton/EMSpinnerButton/EMSpinnerButton.swift; sourceTree = SOURCE_ROOT; };
36 | /* End PBXFileReference section */
37 |
38 | /* Begin PBXFrameworksBuildPhase section */
39 | 8847E6281FC9A6A6004B674D /* Frameworks */ = {
40 | isa = PBXFrameworksBuildPhase;
41 | buildActionMask = 2147483647;
42 | files = (
43 | );
44 | runOnlyForDeploymentPostprocessing = 0;
45 | };
46 | 8847E6321FC9A6A6004B674D /* Frameworks */ = {
47 | isa = PBXFrameworksBuildPhase;
48 | buildActionMask = 2147483647;
49 | files = (
50 | 8847E6361FC9A6A6004B674D /* EMSpinnerButton.framework in Frameworks */,
51 | );
52 | runOnlyForDeploymentPostprocessing = 0;
53 | };
54 | /* End PBXFrameworksBuildPhase section */
55 |
56 | /* Begin PBXGroup section */
57 | 8847E6221FC9A6A6004B674D = {
58 | isa = PBXGroup;
59 | children = (
60 | 8847E62E1FC9A6A6004B674D /* EMSpinnerButton */,
61 | 8847E6391FC9A6A6004B674D /* EMSpinnerButtonTests */,
62 | 8847E62D1FC9A6A6004B674D /* Products */,
63 | );
64 | sourceTree = "";
65 | };
66 | 8847E62D1FC9A6A6004B674D /* Products */ = {
67 | isa = PBXGroup;
68 | children = (
69 | 8847E62C1FC9A6A6004B674D /* EMSpinnerButton.framework */,
70 | 8847E6351FC9A6A6004B674D /* EMSpinnerButtonTests.xctest */,
71 | );
72 | name = Products;
73 | sourceTree = "";
74 | };
75 | 8847E62E1FC9A6A6004B674D /* EMSpinnerButton */ = {
76 | isa = PBXGroup;
77 | children = (
78 | 88CB43C51FCF95DA0026771C /* EMSpinnerButton */,
79 | 8847E62F1FC9A6A6004B674D /* EMSpinnerButton.h */,
80 | 8847E6301FC9A6A6004B674D /* Info.plist */,
81 | );
82 | path = EMSpinnerButton;
83 | sourceTree = "";
84 | };
85 | 8847E6391FC9A6A6004B674D /* EMSpinnerButtonTests */ = {
86 | isa = PBXGroup;
87 | children = (
88 | 8847E63A1FC9A6A6004B674D /* EMSpinnerButtonTests.swift */,
89 | 8847E63C1FC9A6A6004B674D /* Info.plist */,
90 | );
91 | path = EMSpinnerButtonTests;
92 | sourceTree = "";
93 | };
94 | 88CB43C51FCF95DA0026771C /* EMSpinnerButton */ = {
95 | isa = PBXGroup;
96 | children = (
97 | 88CB43C71FCF961E0026771C /* EMSpinnerButton.swift */,
98 | 88CB43C61FCF961E0026771C /* EMSpinnerLayer.swift */,
99 | );
100 | name = EMSpinnerButton;
101 | sourceTree = "";
102 | };
103 | /* End PBXGroup section */
104 |
105 | /* Begin PBXHeadersBuildPhase section */
106 | 8847E6291FC9A6A6004B674D /* Headers */ = {
107 | isa = PBXHeadersBuildPhase;
108 | buildActionMask = 2147483647;
109 | files = (
110 | 8847E63D1FC9A6A6004B674D /* EMSpinnerButton.h in Headers */,
111 | );
112 | runOnlyForDeploymentPostprocessing = 0;
113 | };
114 | /* End PBXHeadersBuildPhase section */
115 |
116 | /* Begin PBXNativeTarget section */
117 | 8847E62B1FC9A6A6004B674D /* EMSpinnerButton */ = {
118 | isa = PBXNativeTarget;
119 | buildConfigurationList = 8847E6401FC9A6A6004B674D /* Build configuration list for PBXNativeTarget "EMSpinnerButton" */;
120 | buildPhases = (
121 | 8847E6271FC9A6A6004B674D /* Sources */,
122 | 8847E6281FC9A6A6004B674D /* Frameworks */,
123 | 8847E6291FC9A6A6004B674D /* Headers */,
124 | 8847E62A1FC9A6A6004B674D /* Resources */,
125 | );
126 | buildRules = (
127 | );
128 | dependencies = (
129 | );
130 | name = EMSpinnerButton;
131 | productName = EMSpinnerButton;
132 | productReference = 8847E62C1FC9A6A6004B674D /* EMSpinnerButton.framework */;
133 | productType = "com.apple.product-type.framework";
134 | };
135 | 8847E6341FC9A6A6004B674D /* EMSpinnerButtonTests */ = {
136 | isa = PBXNativeTarget;
137 | buildConfigurationList = 8847E6431FC9A6A6004B674D /* Build configuration list for PBXNativeTarget "EMSpinnerButtonTests" */;
138 | buildPhases = (
139 | 8847E6311FC9A6A6004B674D /* Sources */,
140 | 8847E6321FC9A6A6004B674D /* Frameworks */,
141 | 8847E6331FC9A6A6004B674D /* Resources */,
142 | );
143 | buildRules = (
144 | );
145 | dependencies = (
146 | 8847E6381FC9A6A6004B674D /* PBXTargetDependency */,
147 | );
148 | name = EMSpinnerButtonTests;
149 | productName = EMSpinnerButtonTests;
150 | productReference = 8847E6351FC9A6A6004B674D /* EMSpinnerButtonTests.xctest */;
151 | productType = "com.apple.product-type.bundle.unit-test";
152 | };
153 | /* End PBXNativeTarget section */
154 |
155 | /* Begin PBXProject section */
156 | 8847E6231FC9A6A6004B674D /* Project object */ = {
157 | isa = PBXProject;
158 | attributes = {
159 | LastSwiftUpdateCheck = 0910;
160 | LastUpgradeCheck = 1010;
161 | ORGANIZATIONNAME = "Eduardo Moll";
162 | TargetAttributes = {
163 | 8847E62B1FC9A6A6004B674D = {
164 | CreatedOnToolsVersion = 9.1;
165 | LastSwiftMigration = 0910;
166 | ProvisioningStyle = Automatic;
167 | };
168 | 8847E6341FC9A6A6004B674D = {
169 | CreatedOnToolsVersion = 9.1;
170 | LastSwiftMigration = 1010;
171 | ProvisioningStyle = Automatic;
172 | };
173 | };
174 | };
175 | buildConfigurationList = 8847E6261FC9A6A6004B674D /* Build configuration list for PBXProject "EMSpinnerButton" */;
176 | compatibilityVersion = "Xcode 8.0";
177 | developmentRegion = en;
178 | hasScannedForEncodings = 0;
179 | knownRegions = (
180 | en,
181 | );
182 | mainGroup = 8847E6221FC9A6A6004B674D;
183 | productRefGroup = 8847E62D1FC9A6A6004B674D /* Products */;
184 | projectDirPath = "";
185 | projectRoot = "";
186 | targets = (
187 | 8847E62B1FC9A6A6004B674D /* EMSpinnerButton */,
188 | 8847E6341FC9A6A6004B674D /* EMSpinnerButtonTests */,
189 | );
190 | };
191 | /* End PBXProject section */
192 |
193 | /* Begin PBXResourcesBuildPhase section */
194 | 8847E62A1FC9A6A6004B674D /* Resources */ = {
195 | isa = PBXResourcesBuildPhase;
196 | buildActionMask = 2147483647;
197 | files = (
198 | );
199 | runOnlyForDeploymentPostprocessing = 0;
200 | };
201 | 8847E6331FC9A6A6004B674D /* Resources */ = {
202 | isa = PBXResourcesBuildPhase;
203 | buildActionMask = 2147483647;
204 | files = (
205 | );
206 | runOnlyForDeploymentPostprocessing = 0;
207 | };
208 | /* End PBXResourcesBuildPhase section */
209 |
210 | /* Begin PBXSourcesBuildPhase section */
211 | 8847E6271FC9A6A6004B674D /* Sources */ = {
212 | isa = PBXSourcesBuildPhase;
213 | buildActionMask = 2147483647;
214 | files = (
215 | 88CB43C81FCF961E0026771C /* EMSpinnerLayer.swift in Sources */,
216 | 88CB43C91FCF961E0026771C /* EMSpinnerButton.swift in Sources */,
217 | );
218 | runOnlyForDeploymentPostprocessing = 0;
219 | };
220 | 8847E6311FC9A6A6004B674D /* Sources */ = {
221 | isa = PBXSourcesBuildPhase;
222 | buildActionMask = 2147483647;
223 | files = (
224 | 8847E63B1FC9A6A6004B674D /* EMSpinnerButtonTests.swift in Sources */,
225 | );
226 | runOnlyForDeploymentPostprocessing = 0;
227 | };
228 | /* End PBXSourcesBuildPhase section */
229 |
230 | /* Begin PBXTargetDependency section */
231 | 8847E6381FC9A6A6004B674D /* PBXTargetDependency */ = {
232 | isa = PBXTargetDependency;
233 | target = 8847E62B1FC9A6A6004B674D /* EMSpinnerButton */;
234 | targetProxy = 8847E6371FC9A6A6004B674D /* PBXContainerItemProxy */;
235 | };
236 | /* End PBXTargetDependency section */
237 |
238 | /* Begin XCBuildConfiguration section */
239 | 8847E63E1FC9A6A6004B674D /* Debug */ = {
240 | isa = XCBuildConfiguration;
241 | buildSettings = {
242 | ALWAYS_SEARCH_USER_PATHS = NO;
243 | CLANG_ANALYZER_NONNULL = YES;
244 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
245 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
246 | CLANG_CXX_LIBRARY = "libc++";
247 | CLANG_ENABLE_MODULES = YES;
248 | CLANG_ENABLE_OBJC_ARC = YES;
249 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
250 | CLANG_WARN_BOOL_CONVERSION = YES;
251 | CLANG_WARN_COMMA = YES;
252 | CLANG_WARN_CONSTANT_CONVERSION = YES;
253 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
254 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
255 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
256 | CLANG_WARN_EMPTY_BODY = YES;
257 | CLANG_WARN_ENUM_CONVERSION = YES;
258 | CLANG_WARN_INFINITE_RECURSION = YES;
259 | CLANG_WARN_INT_CONVERSION = YES;
260 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
261 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
262 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
263 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
264 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
265 | CLANG_WARN_STRICT_PROTOTYPES = YES;
266 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
267 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
268 | CLANG_WARN_UNREACHABLE_CODE = YES;
269 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
270 | CODE_SIGN_IDENTITY = "iPhone Developer";
271 | COPY_PHASE_STRIP = NO;
272 | CURRENT_PROJECT_VERSION = 1;
273 | DEBUG_INFORMATION_FORMAT = dwarf;
274 | ENABLE_STRICT_OBJC_MSGSEND = YES;
275 | ENABLE_TESTABILITY = YES;
276 | GCC_C_LANGUAGE_STANDARD = gnu11;
277 | GCC_DYNAMIC_NO_PIC = NO;
278 | GCC_NO_COMMON_BLOCKS = YES;
279 | GCC_OPTIMIZATION_LEVEL = 0;
280 | GCC_PREPROCESSOR_DEFINITIONS = (
281 | "DEBUG=1",
282 | "$(inherited)",
283 | );
284 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
285 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
286 | GCC_WARN_UNDECLARED_SELECTOR = YES;
287 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
288 | GCC_WARN_UNUSED_FUNCTION = YES;
289 | GCC_WARN_UNUSED_VARIABLE = YES;
290 | IPHONEOS_DEPLOYMENT_TARGET = 11.1;
291 | MTL_ENABLE_DEBUG_INFO = YES;
292 | ONLY_ACTIVE_ARCH = YES;
293 | SDKROOT = iphoneos;
294 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
295 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
296 | VERSIONING_SYSTEM = "apple-generic";
297 | VERSION_INFO_PREFIX = "";
298 | };
299 | name = Debug;
300 | };
301 | 8847E63F1FC9A6A6004B674D /* Release */ = {
302 | isa = XCBuildConfiguration;
303 | buildSettings = {
304 | ALWAYS_SEARCH_USER_PATHS = NO;
305 | CLANG_ANALYZER_NONNULL = YES;
306 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
307 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
308 | CLANG_CXX_LIBRARY = "libc++";
309 | CLANG_ENABLE_MODULES = YES;
310 | CLANG_ENABLE_OBJC_ARC = YES;
311 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
312 | CLANG_WARN_BOOL_CONVERSION = YES;
313 | CLANG_WARN_COMMA = YES;
314 | CLANG_WARN_CONSTANT_CONVERSION = YES;
315 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
316 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
317 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
318 | CLANG_WARN_EMPTY_BODY = YES;
319 | CLANG_WARN_ENUM_CONVERSION = YES;
320 | CLANG_WARN_INFINITE_RECURSION = YES;
321 | CLANG_WARN_INT_CONVERSION = YES;
322 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
323 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
324 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
325 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
326 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
327 | CLANG_WARN_STRICT_PROTOTYPES = YES;
328 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
329 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
330 | CLANG_WARN_UNREACHABLE_CODE = YES;
331 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
332 | CODE_SIGN_IDENTITY = "iPhone Developer";
333 | COPY_PHASE_STRIP = NO;
334 | CURRENT_PROJECT_VERSION = 1;
335 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
336 | ENABLE_NS_ASSERTIONS = NO;
337 | ENABLE_STRICT_OBJC_MSGSEND = YES;
338 | GCC_C_LANGUAGE_STANDARD = gnu11;
339 | GCC_NO_COMMON_BLOCKS = YES;
340 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
341 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
342 | GCC_WARN_UNDECLARED_SELECTOR = YES;
343 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
344 | GCC_WARN_UNUSED_FUNCTION = YES;
345 | GCC_WARN_UNUSED_VARIABLE = YES;
346 | IPHONEOS_DEPLOYMENT_TARGET = 11.1;
347 | MTL_ENABLE_DEBUG_INFO = NO;
348 | SDKROOT = iphoneos;
349 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
350 | VALIDATE_PRODUCT = YES;
351 | VERSIONING_SYSTEM = "apple-generic";
352 | VERSION_INFO_PREFIX = "";
353 | };
354 | name = Release;
355 | };
356 | 8847E6411FC9A6A6004B674D /* Debug */ = {
357 | isa = XCBuildConfiguration;
358 | buildSettings = {
359 | CLANG_ENABLE_MODULES = YES;
360 | CODE_SIGN_IDENTITY = "";
361 | CODE_SIGN_STYLE = Automatic;
362 | DEFINES_MODULE = YES;
363 | DEVELOPMENT_TEAM = K2T5FY27PH;
364 | DYLIB_COMPATIBILITY_VERSION = 1;
365 | DYLIB_CURRENT_VERSION = 1;
366 | DYLIB_INSTALL_NAME_BASE = "@rpath";
367 | INFOPLIST_FILE = EMSpinnerButton/Info.plist;
368 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
369 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
370 | PRODUCT_BUNDLE_IDENTIFIER = com.eduardomoll.EMSpinnerButton;
371 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
372 | SKIP_INSTALL = YES;
373 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
374 | SWIFT_VERSION = 4.2;
375 | TARGETED_DEVICE_FAMILY = "1,2";
376 | };
377 | name = Debug;
378 | };
379 | 8847E6421FC9A6A6004B674D /* Release */ = {
380 | isa = XCBuildConfiguration;
381 | buildSettings = {
382 | CLANG_ENABLE_MODULES = YES;
383 | CODE_SIGN_IDENTITY = "";
384 | CODE_SIGN_STYLE = Automatic;
385 | DEFINES_MODULE = YES;
386 | DEVELOPMENT_TEAM = K2T5FY27PH;
387 | DYLIB_COMPATIBILITY_VERSION = 1;
388 | DYLIB_CURRENT_VERSION = 1;
389 | DYLIB_INSTALL_NAME_BASE = "@rpath";
390 | INFOPLIST_FILE = EMSpinnerButton/Info.plist;
391 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
392 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
393 | PRODUCT_BUNDLE_IDENTIFIER = com.eduardomoll.EMSpinnerButton;
394 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
395 | SKIP_INSTALL = YES;
396 | SWIFT_VERSION = 4.2;
397 | TARGETED_DEVICE_FAMILY = "1,2";
398 | };
399 | name = Release;
400 | };
401 | 8847E6441FC9A6A6004B674D /* Debug */ = {
402 | isa = XCBuildConfiguration;
403 | buildSettings = {
404 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
405 | CODE_SIGN_STYLE = Automatic;
406 | DEVELOPMENT_TEAM = K2T5FY27PH;
407 | INFOPLIST_FILE = EMSpinnerButtonTests/Info.plist;
408 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
409 | PRODUCT_BUNDLE_IDENTIFIER = com.eduardomoll.EMSpinnerButtonTests;
410 | PRODUCT_NAME = "$(TARGET_NAME)";
411 | SWIFT_VERSION = 4.2;
412 | TARGETED_DEVICE_FAMILY = "1,2";
413 | };
414 | name = Debug;
415 | };
416 | 8847E6451FC9A6A6004B674D /* Release */ = {
417 | isa = XCBuildConfiguration;
418 | buildSettings = {
419 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
420 | CODE_SIGN_STYLE = Automatic;
421 | DEVELOPMENT_TEAM = K2T5FY27PH;
422 | INFOPLIST_FILE = EMSpinnerButtonTests/Info.plist;
423 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
424 | PRODUCT_BUNDLE_IDENTIFIER = com.eduardomoll.EMSpinnerButtonTests;
425 | PRODUCT_NAME = "$(TARGET_NAME)";
426 | SWIFT_VERSION = 4.2;
427 | TARGETED_DEVICE_FAMILY = "1,2";
428 | };
429 | name = Release;
430 | };
431 | /* End XCBuildConfiguration section */
432 |
433 | /* Begin XCConfigurationList section */
434 | 8847E6261FC9A6A6004B674D /* Build configuration list for PBXProject "EMSpinnerButton" */ = {
435 | isa = XCConfigurationList;
436 | buildConfigurations = (
437 | 8847E63E1FC9A6A6004B674D /* Debug */,
438 | 8847E63F1FC9A6A6004B674D /* Release */,
439 | );
440 | defaultConfigurationIsVisible = 0;
441 | defaultConfigurationName = Release;
442 | };
443 | 8847E6401FC9A6A6004B674D /* Build configuration list for PBXNativeTarget "EMSpinnerButton" */ = {
444 | isa = XCConfigurationList;
445 | buildConfigurations = (
446 | 8847E6411FC9A6A6004B674D /* Debug */,
447 | 8847E6421FC9A6A6004B674D /* Release */,
448 | );
449 | defaultConfigurationIsVisible = 0;
450 | defaultConfigurationName = Release;
451 | };
452 | 8847E6431FC9A6A6004B674D /* Build configuration list for PBXNativeTarget "EMSpinnerButtonTests" */ = {
453 | isa = XCConfigurationList;
454 | buildConfigurations = (
455 | 8847E6441FC9A6A6004B674D /* Debug */,
456 | 8847E6451FC9A6A6004B674D /* Release */,
457 | );
458 | defaultConfigurationIsVisible = 0;
459 | defaultConfigurationName = Release;
460 | };
461 | /* End XCConfigurationList section */
462 | };
463 | rootObject = 8847E6231FC9A6A6004B674D /* Project object */;
464 | }
465 |
--------------------------------------------------------------------------------