├── DocAssets
├── alanimatable-example-1.gif
├── alanimatable-example-2.gif
├── alanimatable-example-3.gif
├── alanimatable-example-4.gif
└── alanimatable-example-5.gif
├── CHANGELOG.md
├── ALAnimatable.xcodeproj
├── project.xcworkspace
│ └── contents.xcworkspacedata
└── project.pbxproj
├── ALAnimatable
├── ALAnimatable.h
├── Info.plist
└── Animatable.swift
├── LICENSE
├── ALAnimatable.podspec
├── .gitignore
└── README.md
/DocAssets/alanimatable-example-1.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/almata/ALAnimatable/HEAD/DocAssets/alanimatable-example-1.gif
--------------------------------------------------------------------------------
/DocAssets/alanimatable-example-2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/almata/ALAnimatable/HEAD/DocAssets/alanimatable-example-2.gif
--------------------------------------------------------------------------------
/DocAssets/alanimatable-example-3.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/almata/ALAnimatable/HEAD/DocAssets/alanimatable-example-3.gif
--------------------------------------------------------------------------------
/DocAssets/alanimatable-example-4.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/almata/ALAnimatable/HEAD/DocAssets/alanimatable-example-4.gif
--------------------------------------------------------------------------------
/DocAssets/alanimatable-example-5.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/almata/ALAnimatable/HEAD/DocAssets/alanimatable-example-5.gif
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | ### 0.2
2 |
3 | * Add `uniform: AnimatableUniform` parameter to allow subviews animating at different velocities
4 |
5 | ### 0.1
6 |
7 | * Initial version
8 |
--------------------------------------------------------------------------------
/ALAnimatable.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ALAnimatable/ALAnimatable.h:
--------------------------------------------------------------------------------
1 | //
2 | // ALAnimatable.h
3 | // ALAnimatable
4 | //
5 | // Created by Albert Mata Guerra on 09/07/16.
6 | // Copyright © 2016 Albert Mata Guerra. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | //! Project version number for ALAnimatable.
12 | FOUNDATION_EXPORT double ALAnimatableVersionNumber;
13 |
14 | //! Project version string for ALAnimatable.
15 | FOUNDATION_EXPORT const unsigned char ALAnimatableVersionString[];
16 |
17 | // In this header, you should import all the public headers of your framework using statements like #import
18 |
19 |
20 |
--------------------------------------------------------------------------------
/ALAnimatable/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
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 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(CURRENT_PROJECT_VERSION)
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Albert Mata
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 |
--------------------------------------------------------------------------------
/ALAnimatable.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 |
3 | s.name = "ALAnimatable"
4 | s.version = "0.2"
5 | s.summary = "ALAnimatable allows you to animate all subviews in a view at once."
6 | s.description = "ALAnimatable adds an Animatable protocol into your project that lets you animate all subviews in a view at once with just a single line of code, providing you have created your user interface using Auto Layout."
7 | s.homepage = "https://github.com/almata/ALAnimatable"
8 | s.screenshots = "https://raw.githubusercontent.com/almata/ALAnimatable/master/DocAssets/alanimatable-example-1.gif", "https://raw.githubusercontent.com/almata/ALAnimatable/master/DocAssets/alanimatable-example-2.gif", "https://raw.githubusercontent.com/almata/ALAnimatable/master/DocAssets/alanimatable-example-3.gif", "https://raw.githubusercontent.com/almata/ALAnimatable/master/DocAssets/alanimatable-example-4.gif", "https://raw.githubusercontent.com/almata/ALAnimatable/master/DocAssets/alanimatable-example-5.gif"
9 | s.license = "MIT"
10 | s.author = { "Albert Mata" => "hello@albertmata.net" }
11 | s.social_media_url = "http://twitter.com/almata"
12 | s.platform = :ios, "8.0"
13 | s.source = { :git => "https://github.com/almata/ALAnimatable.git", :tag => "0.2" }
14 | s.source_files = "ALAnimatable", "ALAnimatable/**/*.{h,m,swift}"
15 | end
16 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | ALAnimatable_Example/
2 | ALAnimatable_Pod/
3 |
4 | # Xcode
5 | #
6 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
7 |
8 | ## Build generated
9 | build/
10 | DerivedData/
11 | .DS_Store
12 |
13 | ## Various settings
14 | *.pbxuser
15 | !default.pbxuser
16 | *.mode1v3
17 | !default.mode1v3
18 | *.mode2v3
19 | !default.mode2v3
20 | *.perspectivev3
21 | !default.perspectivev3
22 | xcuserdata/
23 |
24 | ## Other
25 | *.moved-aside
26 | *.xcuserstate
27 |
28 | ## Obj-C/Swift specific
29 | *.hmap
30 | *.ipa
31 | *.dSYM.zip
32 | *.dSYM
33 |
34 | ## Playgrounds
35 | timeline.xctimeline
36 | playground.xcworkspace
37 |
38 | # Swift Package Manager
39 | #
40 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
41 | # Packages/
42 | .build/
43 |
44 | # CocoaPods
45 | #
46 | # We recommend against adding the Pods directory to your .gitignore. However
47 | # you should judge for yourself, the pros and cons are mentioned at:
48 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
49 | #
50 | # Pods/
51 |
52 | # Carthage
53 | #
54 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
55 | # Carthage/Checkouts
56 |
57 | Carthage/Build
58 |
59 | # fastlane
60 | #
61 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
62 | # screenshots whenever they are needed.
63 | # For more information about the recommended setup visit:
64 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md
65 |
66 | fastlane/report.xml
67 | fastlane/Preview.html
68 | fastlane/screenshots
69 | fastlane/test_output
70 |
--------------------------------------------------------------------------------
/ALAnimatable/Animatable.swift:
--------------------------------------------------------------------------------
1 | //
2 | // Animatable.swift
3 | // ALAnimatable
4 | //
5 | // Created by Albert Mata Guerra on 09/07/16.
6 | // Copyright © 2016 Albert Mata Guerra. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | extension UIView: Animatable { }
12 |
13 | public protocol Animatable {
14 |
15 | func animateSubviews(from direction: AnimatableDirection, destination: AnimatableDestination,
16 | speed: AnimatableSpeed, origin: AnimatableOrigin,
17 | bouncing: Bool, excluding: Set,
18 | uniform: AnimatableUniform)
19 |
20 | }
21 |
22 | extension Animatable where Self: UIView {
23 |
24 | public func animateSubviews(from direction: AnimatableDirection, destination: AnimatableDestination = .In,
25 | speed: AnimatableSpeed = .Medium, origin: AnimatableOrigin = .Close,
26 | bouncing: Bool = true, excluding: Set = [],
27 | uniform: AnimatableUniform = .Totally) {
28 |
29 | let atts = attributes(direction)
30 | // Filtering not hidden views is not only useful per se but helps dealing with issues regarding UILayoutSupport.
31 | let including = Set(subviews.filter({!$0.hidden})).subtract(excluding)
32 | let damping: CGFloat = bouncing ? 0.5 : 1
33 |
34 | if destination == .In {
35 | constraints.forEach { constraint in
36 | guard let firstItem = constraint.firstItem as? UIView, secondItem = constraint.secondItem as? UIView else { return }
37 | if including.isDisjointWith([firstItem, secondItem]) { return }
38 | if !atts.isDisjointWith([constraint.firstAttribute, constraint.secondAttribute]) {
39 | constraint.constant += origin.rawValue * direction.screenSize() * self.sign(constraint, superview: self, direction: direction)
40 | }
41 | }
42 | setNeedsLayout()
43 | }
44 |
45 | delay(0.01) {
46 |
47 | self.constraints.forEach { constraint in
48 | guard let firstItem = constraint.firstItem as? UIView, secondItem = constraint.secondItem as? UIView else { return }
49 | if including.isDisjointWith([firstItem, secondItem]) { return }
50 | if !atts.isDisjointWith([constraint.firstAttribute, constraint.secondAttribute]) {
51 | let duration = speed.rawValue * uniform.multiplier()
52 | UIView.animateWithDuration(duration, delay: 0, usingSpringWithDamping: damping, initialSpringVelocity: 0, options: [], animations: {
53 | constraint.constant -= origin.rawValue * direction.screenSize() * self.sign(constraint, superview: self, direction: direction)
54 | self.layoutIfNeeded()
55 | }, completion: nil)
56 | }
57 | }
58 |
59 | }
60 |
61 | }
62 |
63 | private func attributes(direction: AnimatableDirection) -> Set {
64 | if direction == .Left || direction == .Right {
65 | return Set([.CenterX, .CenterXWithinMargins, .Leading, .LeadingMargin, .Left, .LeftMargin, .Right, .RightMargin, .Trailing, .TrailingMargin])
66 | } else {
67 | return Set([.Bottom, .BottomMargin, .CenterY, .CenterYWithinMargins, .Top, .TopMargin])
68 | }
69 | }
70 |
71 | private func sign(constraint: NSLayoutConstraint, superview: UIView, direction: AnimatableDirection) -> CGFloat {
72 | guard let firstItem = constraint.firstItem as? UIView, secondItem = constraint.secondItem as? UIView else { return 0 }
73 | if firstItem == superview || firstItem.hidden { return -1 * direction.sign() }
74 | if secondItem == superview || secondItem.hidden { return 1 * direction.sign() }
75 | return 0
76 | }
77 |
78 | private func delay(delay: Double, closure: () -> ()) {
79 | dispatch_after(
80 | dispatch_time(
81 | DISPATCH_TIME_NOW,
82 | Int64(delay * Double(NSEC_PER_SEC))
83 | ),
84 | dispatch_get_main_queue(), closure)
85 | }
86 |
87 | }
88 |
89 | public enum AnimatableSpeed: NSTimeInterval {
90 | case Quick = 0.5
91 | case Medium = 1.0
92 | case Slow = 2.0
93 | }
94 |
95 | public enum AnimatableOrigin: CGFloat {
96 | case Close = 1
97 | case Far = 2
98 | case ReallyFar = 3
99 | }
100 |
101 | public enum AnimatableDestination {
102 | case In, Out
103 | }
104 |
105 | public enum AnimatableDirection {
106 | case Left, Right, Top, Bottom
107 |
108 | func sign() -> CGFloat {
109 | switch self {
110 | case .Left, .Top: return -1
111 | case .Right, .Bottom: return 1
112 | }
113 | }
114 |
115 | func screenSize() -> CGFloat {
116 | switch self {
117 | case .Left, .Right: return UIScreen.mainScreen().bounds.width
118 | case .Top, .Bottom: return UIScreen.mainScreen().bounds.height
119 | }
120 | }
121 | }
122 |
123 | public enum AnimatableUniform {
124 | case Slightly, Nearly, Totally
125 |
126 | func multiplier() -> Double {
127 | switch self {
128 | case .Slightly: return random(0.6, 1.4)
129 | case .Nearly: return random(0.85, 1.15)
130 | case .Totally: return 1.0
131 | }
132 | }
133 |
134 | private func random(min: Double, _ max: Double) -> Double {
135 | return Double(arc4random_uniform(UInt32(max * 1000) - UInt32(min * 1000))) / 1000 + min
136 | }
137 | }
138 |
139 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | # ALAnimatable
9 |
10 | **ALAnimatable** adds an `Animatable` protocol into your project that lets you animate all subviews in a view at once with just a single line of code, providing you have created your user interface using Auto Layout.
11 |
12 | ## Compatibility
13 |
14 | **ALAnimatable** requires iOS 8+ and is compatible with Swift 2 projects using Auto Layout.
15 |
16 | ## Installation
17 |
18 | ### CocoaPods
19 |
20 | Installation for [CocoaPods](https://cocoapods.org) is simple enough:
21 |
22 | use_frameworks!
23 | pod 'ALAnimatable'
24 |
25 | And `import ALAnimatable` in the files you would like to use it.
26 |
27 | ### Old school
28 |
29 | Just drag the file `Animatable.swift` into your project. That is all you really need.
30 |
31 | ## Usage
32 |
33 | The full signature for the `animateSubviews` method includes more options appart from the mandatory `direction`:
34 |
35 | ```swift
36 | func animateSubviews(from direction: AnimatableDirection, destination: AnimatableDestination,
37 | speed: AnimatableSpeed, origin: AnimatableOrigin,
38 | bouncing: Bool, excluding: Set,
39 | uniform: AnimatableUniform)
40 | ```
41 |
42 | * `direction: AnimatableDirection` can be `Right`, `Left`, `Top` or `Bottom` and sets where the subviews are going to animate from.
43 | * `destination: AnimatableDestination` can be `In` (default option) or `Out` and indicates whether all subviews are supposed to animate to enter into the view or to go away.
44 | * `speed: AnimatableSpeed` can be `Quick`, `Medium` (default option) or `Slow` and sets the duration for the animation.
45 | * `origin: AnimatableOrigin` can be `Close` (default option), `Far` or `ReallyFar` and indicates how far the views are placed at the beginning of the animation (or how far they will go if it's an `Out` animation). This impacts a bit, but not much, on the subviews movement.
46 | * `bouncing: Bool` can obviously be `true` (default option) or `false` and sets whether or not the subviews will bounce at the end of the animation.
47 | * `excluding: Set` expects a set (so you can pass an array) with all your view's subviews that you **do not** want to be animated. Its default value is an empty set, so all subviews get animated.
48 | * `uniform: AnimatableUniform` can be `Slightly`, `Nearly` or `Totally` (default option) and allows subviews animating at different velocities.
49 |
50 | ### So, how does this work?
51 |
52 | 1. First of all, you need to create your user interface using Auto Layout (the AL prefix in `ALAnimatable` is actually for Auto Layout, not for Albert). You do not need to set any special constraint or priority or whatever. Just forget you are going to animate the views and design your interface as you would normally do.
53 |
54 | 2. Secondly, in your code you call that single line of code on the main view that contains all the rest. It may very well be the main `UIViewController`'s `view`.
55 |
56 | 3. Nothing else.
57 |
58 | From the source code point of view, `ALAnimatable` creates an `Animatable` protocol and adds an extension with all its functionality that can only be adopted by `UIView`. It also sets another extension to say that `UIView` actually adopts `Animatable`. If you do not want every single `UIView` in your project to adopt `Animatable`, you can remove the `extension UIView: Animatable { }` line and then ensure a `UIView` subclass of yours adopts the protocol.
59 |
60 | ### What NSLayoutAttribute options can be used so they get animated?
61 |
62 | All options that make sense for horizontal or vertical constraints. That is `CenterX`, `CenterXWithinMargins`, `Leading`, `LeadingMargin`, `Left`, `LeftMargin`, `Right`, `RightMargin`, `Trailing` and `TrailingMargin` for horizontal animations and `Bottom`, `BottomMargin`, `CenterY`, `CenterYWithinMargins`, `Top` and `TopMargin` for vertical animations.
63 |
64 | ### Does it work well with views inside views inside views... or views inside stack views inside stack views inside...?
65 |
66 | Yes, it does. And good luck cleaning all those warnings in Interface Builder if you are using nested stack views.
67 |
68 | ## Some examples
69 |
70 | ### Example 1
71 |
72 | To animate all subviews in main `UIViewController`'s `view` (except the buttons at the bottom) coming from the right:
73 |
74 | ```swift
75 | view.animateSubviews(from: .Right, excluding: [buttons])
76 | ```
77 |
78 |
79 |
80 | ### Example 2
81 |
82 | To animate all subviews in main `UIViewController`'s `view` (except the buttons at the bottom) coming from the left and moving out of the screen slowly but going far:
83 |
84 | ```swift
85 | view.animateSubviews(from: .Left, destination: .Out, speed: .Slow, origin: .Far, excluding: [buttons])
86 | ```
87 |
88 |
89 |
90 | ### Example 3
91 |
92 | To animate all subviews in main `UIViewController`'s `view` (except the buttons at the bottom) coming from the top and really far (so they will appear abruptly):
93 |
94 | ```swift
95 | view.animateSubviews(from: .Top, origin: .ReallyFar, excluding: [buttons])
96 | ```
97 |
98 |
99 |
100 | ### Example 4
101 |
102 | To animate all subviews in main `UIViewController`'s `view` (except the buttons at the bottom) coming from the bottom and without final bouncing:
103 |
104 | ```swift
105 | view.animateSubviews(from: .Bottom, bouncing: false, excluding: [buttons])
106 | ```
107 |
108 |
109 |
110 | ### Example 5
111 |
112 | To animate all subviews in main `UIViewController`'s `view` (except the buttons at the bottom) coming from the right and setting `uniform` so each of the subviews gets animated at a different velocity:
113 |
114 | ```swift
115 | view.animateSubviews(from: .Right, excluding: [buttons], uniform: .Slightly)
116 | ```
117 |
118 |
119 |
120 | ## Some considerations to keep in mind:
121 |
122 | * As expected, the Auto Layout system needs to be valid for `ALAnimatable` to work reliably.
123 |
124 | * The `excluding` parameter lets you set some subviews you do not want to be animated as long as they are placed using constraints involving the main view or other subviews that are also excluded from the animation process. If you pass a subview in `excluding` but its position in the screen is set by constraints involving other subviews that are going to be animated, your subview will be as well.
125 |
126 | ## Author
127 |
128 | Albert Mata ([@almata](https://twitter.com/almata) on Twitter). Please find some more information about me and my work at my website [albertmata.net](http://www.albertmata.net).
129 |
130 | ## Hire me
131 |
132 | I'm currently based in Barcelona and taking projects (permanent or contractor) all over Europe as long as you are OK with total or partial remote work (say I can be onsite one or two weeks a month if you need it). For more information, please check my projects at [albertmata.net/apps](http://albertmata.net/apps) or contact me at **hello@albertmata.net**.
133 |
134 | ## License
135 |
136 | **ALAnimatable** uses the MIT license. Please file an issue if you have any questions or if you would like to share how you are using this tool.
137 |
--------------------------------------------------------------------------------
/ALAnimatable.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 40C39F361D3162D40099A77A /* ALAnimatable.h in Headers */ = {isa = PBXBuildFile; fileRef = 40C39F351D3162D40099A77A /* ALAnimatable.h */; settings = {ATTRIBUTES = (Public, ); }; };
11 | 40C39F3E1D31631C0099A77A /* Animatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40C39F3D1D31631C0099A77A /* Animatable.swift */; };
12 | /* End PBXBuildFile section */
13 |
14 | /* Begin PBXFileReference section */
15 | 40C39F321D3162D40099A77A /* ALAnimatable.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ALAnimatable.framework; sourceTree = BUILT_PRODUCTS_DIR; };
16 | 40C39F351D3162D40099A77A /* ALAnimatable.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALAnimatable.h; sourceTree = ""; };
17 | 40C39F371D3162D40099A77A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
18 | 40C39F3D1D31631C0099A77A /* Animatable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Animatable.swift; sourceTree = ""; };
19 | /* End PBXFileReference section */
20 |
21 | /* Begin PBXFrameworksBuildPhase section */
22 | 40C39F2E1D3162D40099A77A /* Frameworks */ = {
23 | isa = PBXFrameworksBuildPhase;
24 | buildActionMask = 2147483647;
25 | files = (
26 | );
27 | runOnlyForDeploymentPostprocessing = 0;
28 | };
29 | /* End PBXFrameworksBuildPhase section */
30 |
31 | /* Begin PBXGroup section */
32 | 40C39F281D3162D40099A77A = {
33 | isa = PBXGroup;
34 | children = (
35 | 40C39F341D3162D40099A77A /* ALAnimatable */,
36 | 40C39F331D3162D40099A77A /* Products */,
37 | );
38 | sourceTree = "";
39 | };
40 | 40C39F331D3162D40099A77A /* Products */ = {
41 | isa = PBXGroup;
42 | children = (
43 | 40C39F321D3162D40099A77A /* ALAnimatable.framework */,
44 | );
45 | name = Products;
46 | sourceTree = "";
47 | };
48 | 40C39F341D3162D40099A77A /* ALAnimatable */ = {
49 | isa = PBXGroup;
50 | children = (
51 | 40C39F3D1D31631C0099A77A /* Animatable.swift */,
52 | 40C39F351D3162D40099A77A /* ALAnimatable.h */,
53 | 40C39F371D3162D40099A77A /* Info.plist */,
54 | );
55 | path = ALAnimatable;
56 | sourceTree = "";
57 | };
58 | /* End PBXGroup section */
59 |
60 | /* Begin PBXHeadersBuildPhase section */
61 | 40C39F2F1D3162D40099A77A /* Headers */ = {
62 | isa = PBXHeadersBuildPhase;
63 | buildActionMask = 2147483647;
64 | files = (
65 | 40C39F361D3162D40099A77A /* ALAnimatable.h in Headers */,
66 | );
67 | runOnlyForDeploymentPostprocessing = 0;
68 | };
69 | /* End PBXHeadersBuildPhase section */
70 |
71 | /* Begin PBXNativeTarget section */
72 | 40C39F311D3162D40099A77A /* ALAnimatable */ = {
73 | isa = PBXNativeTarget;
74 | buildConfigurationList = 40C39F3A1D3162D40099A77A /* Build configuration list for PBXNativeTarget "ALAnimatable" */;
75 | buildPhases = (
76 | 40C39F2D1D3162D40099A77A /* Sources */,
77 | 40C39F2E1D3162D40099A77A /* Frameworks */,
78 | 40C39F2F1D3162D40099A77A /* Headers */,
79 | 40C39F301D3162D40099A77A /* Resources */,
80 | );
81 | buildRules = (
82 | );
83 | dependencies = (
84 | );
85 | name = ALAnimatable;
86 | productName = ALAnimatable;
87 | productReference = 40C39F321D3162D40099A77A /* ALAnimatable.framework */;
88 | productType = "com.apple.product-type.framework";
89 | };
90 | /* End PBXNativeTarget section */
91 |
92 | /* Begin PBXProject section */
93 | 40C39F291D3162D40099A77A /* Project object */ = {
94 | isa = PBXProject;
95 | attributes = {
96 | LastUpgradeCheck = 0730;
97 | ORGANIZATIONNAME = "Albert Mata Guerra";
98 | TargetAttributes = {
99 | 40C39F311D3162D40099A77A = {
100 | CreatedOnToolsVersion = 7.3.1;
101 | };
102 | };
103 | };
104 | buildConfigurationList = 40C39F2C1D3162D40099A77A /* Build configuration list for PBXProject "ALAnimatable" */;
105 | compatibilityVersion = "Xcode 3.2";
106 | developmentRegion = English;
107 | hasScannedForEncodings = 0;
108 | knownRegions = (
109 | en,
110 | );
111 | mainGroup = 40C39F281D3162D40099A77A;
112 | productRefGroup = 40C39F331D3162D40099A77A /* Products */;
113 | projectDirPath = "";
114 | projectRoot = "";
115 | targets = (
116 | 40C39F311D3162D40099A77A /* ALAnimatable */,
117 | );
118 | };
119 | /* End PBXProject section */
120 |
121 | /* Begin PBXResourcesBuildPhase section */
122 | 40C39F301D3162D40099A77A /* Resources */ = {
123 | isa = PBXResourcesBuildPhase;
124 | buildActionMask = 2147483647;
125 | files = (
126 | );
127 | runOnlyForDeploymentPostprocessing = 0;
128 | };
129 | /* End PBXResourcesBuildPhase section */
130 |
131 | /* Begin PBXSourcesBuildPhase section */
132 | 40C39F2D1D3162D40099A77A /* Sources */ = {
133 | isa = PBXSourcesBuildPhase;
134 | buildActionMask = 2147483647;
135 | files = (
136 | 40C39F3E1D31631C0099A77A /* Animatable.swift in Sources */,
137 | );
138 | runOnlyForDeploymentPostprocessing = 0;
139 | };
140 | /* End PBXSourcesBuildPhase section */
141 |
142 | /* Begin XCBuildConfiguration section */
143 | 40C39F381D3162D40099A77A /* Debug */ = {
144 | isa = XCBuildConfiguration;
145 | buildSettings = {
146 | ALWAYS_SEARCH_USER_PATHS = NO;
147 | CLANG_ANALYZER_NONNULL = YES;
148 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
149 | CLANG_CXX_LIBRARY = "libc++";
150 | CLANG_ENABLE_MODULES = YES;
151 | CLANG_ENABLE_OBJC_ARC = YES;
152 | CLANG_WARN_BOOL_CONVERSION = YES;
153 | CLANG_WARN_CONSTANT_CONVERSION = YES;
154 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
155 | CLANG_WARN_EMPTY_BODY = YES;
156 | CLANG_WARN_ENUM_CONVERSION = YES;
157 | CLANG_WARN_INT_CONVERSION = YES;
158 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
159 | CLANG_WARN_UNREACHABLE_CODE = YES;
160 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
161 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
162 | COPY_PHASE_STRIP = NO;
163 | CURRENT_PROJECT_VERSION = 1;
164 | DEBUG_INFORMATION_FORMAT = dwarf;
165 | ENABLE_STRICT_OBJC_MSGSEND = YES;
166 | ENABLE_TESTABILITY = YES;
167 | GCC_C_LANGUAGE_STANDARD = gnu99;
168 | GCC_DYNAMIC_NO_PIC = NO;
169 | GCC_NO_COMMON_BLOCKS = YES;
170 | GCC_OPTIMIZATION_LEVEL = 0;
171 | GCC_PREPROCESSOR_DEFINITIONS = (
172 | "DEBUG=1",
173 | "$(inherited)",
174 | );
175 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
176 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
177 | GCC_WARN_UNDECLARED_SELECTOR = YES;
178 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
179 | GCC_WARN_UNUSED_FUNCTION = YES;
180 | GCC_WARN_UNUSED_VARIABLE = YES;
181 | IPHONEOS_DEPLOYMENT_TARGET = 9.3;
182 | MTL_ENABLE_DEBUG_INFO = YES;
183 | ONLY_ACTIVE_ARCH = YES;
184 | SDKROOT = iphoneos;
185 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
186 | TARGETED_DEVICE_FAMILY = "1,2";
187 | VERSIONING_SYSTEM = "apple-generic";
188 | VERSION_INFO_PREFIX = "";
189 | };
190 | name = Debug;
191 | };
192 | 40C39F391D3162D40099A77A /* Release */ = {
193 | isa = XCBuildConfiguration;
194 | buildSettings = {
195 | ALWAYS_SEARCH_USER_PATHS = NO;
196 | CLANG_ANALYZER_NONNULL = YES;
197 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
198 | CLANG_CXX_LIBRARY = "libc++";
199 | CLANG_ENABLE_MODULES = YES;
200 | CLANG_ENABLE_OBJC_ARC = YES;
201 | CLANG_WARN_BOOL_CONVERSION = YES;
202 | CLANG_WARN_CONSTANT_CONVERSION = YES;
203 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
204 | CLANG_WARN_EMPTY_BODY = YES;
205 | CLANG_WARN_ENUM_CONVERSION = YES;
206 | CLANG_WARN_INT_CONVERSION = YES;
207 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
208 | CLANG_WARN_UNREACHABLE_CODE = YES;
209 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
210 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
211 | COPY_PHASE_STRIP = NO;
212 | CURRENT_PROJECT_VERSION = 1;
213 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
214 | ENABLE_NS_ASSERTIONS = NO;
215 | ENABLE_STRICT_OBJC_MSGSEND = YES;
216 | GCC_C_LANGUAGE_STANDARD = gnu99;
217 | GCC_NO_COMMON_BLOCKS = YES;
218 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
219 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
220 | GCC_WARN_UNDECLARED_SELECTOR = YES;
221 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
222 | GCC_WARN_UNUSED_FUNCTION = YES;
223 | GCC_WARN_UNUSED_VARIABLE = YES;
224 | IPHONEOS_DEPLOYMENT_TARGET = 9.3;
225 | MTL_ENABLE_DEBUG_INFO = NO;
226 | SDKROOT = iphoneos;
227 | TARGETED_DEVICE_FAMILY = "1,2";
228 | VALIDATE_PRODUCT = YES;
229 | VERSIONING_SYSTEM = "apple-generic";
230 | VERSION_INFO_PREFIX = "";
231 | };
232 | name = Release;
233 | };
234 | 40C39F3B1D3162D40099A77A /* Debug */ = {
235 | isa = XCBuildConfiguration;
236 | buildSettings = {
237 | CLANG_ENABLE_MODULES = YES;
238 | DEFINES_MODULE = YES;
239 | DYLIB_COMPATIBILITY_VERSION = 1;
240 | DYLIB_CURRENT_VERSION = 1;
241 | DYLIB_INSTALL_NAME_BASE = "@rpath";
242 | INFOPLIST_FILE = ALAnimatable/Info.plist;
243 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
244 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
245 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
246 | PRODUCT_BUNDLE_IDENTIFIER = com.albertmata.ALAnimatable;
247 | PRODUCT_NAME = "$(TARGET_NAME)";
248 | SKIP_INSTALL = YES;
249 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
250 | };
251 | name = Debug;
252 | };
253 | 40C39F3C1D3162D40099A77A /* Release */ = {
254 | isa = XCBuildConfiguration;
255 | buildSettings = {
256 | CLANG_ENABLE_MODULES = YES;
257 | DEFINES_MODULE = YES;
258 | DYLIB_COMPATIBILITY_VERSION = 1;
259 | DYLIB_CURRENT_VERSION = 1;
260 | DYLIB_INSTALL_NAME_BASE = "@rpath";
261 | INFOPLIST_FILE = ALAnimatable/Info.plist;
262 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
263 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
264 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
265 | PRODUCT_BUNDLE_IDENTIFIER = com.albertmata.ALAnimatable;
266 | PRODUCT_NAME = "$(TARGET_NAME)";
267 | SKIP_INSTALL = YES;
268 | };
269 | name = Release;
270 | };
271 | /* End XCBuildConfiguration section */
272 |
273 | /* Begin XCConfigurationList section */
274 | 40C39F2C1D3162D40099A77A /* Build configuration list for PBXProject "ALAnimatable" */ = {
275 | isa = XCConfigurationList;
276 | buildConfigurations = (
277 | 40C39F381D3162D40099A77A /* Debug */,
278 | 40C39F391D3162D40099A77A /* Release */,
279 | );
280 | defaultConfigurationIsVisible = 0;
281 | defaultConfigurationName = Release;
282 | };
283 | 40C39F3A1D3162D40099A77A /* Build configuration list for PBXNativeTarget "ALAnimatable" */ = {
284 | isa = XCConfigurationList;
285 | buildConfigurations = (
286 | 40C39F3B1D3162D40099A77A /* Debug */,
287 | 40C39F3C1D3162D40099A77A /* Release */,
288 | );
289 | defaultConfigurationIsVisible = 0;
290 | defaultConfigurationName = Release;
291 | };
292 | /* End XCConfigurationList section */
293 | };
294 | rootObject = 40C39F291D3162D40099A77A /* Project object */;
295 | }
296 |
--------------------------------------------------------------------------------