├── .github └── FUNDING.yml ├── .travis.yml ├── LICENSE ├── Podfile ├── Podfile.lock ├── RBBAnimation.podspec ├── RBBAnimation.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcshareddata │ └── xcschemes │ ├── RBBAnimation Mac.xcscheme │ └── RBBAnimation iOS.xcscheme ├── RBBAnimation.xcworkspace └── contents.xcworkspacedata ├── RBBAnimation ├── NSColor+PlatformIndependence.h ├── NSColor+PlatformIndependence.m ├── NSValue+PlatformIndependence.h ├── NSValue+PlatformIndependence.m ├── RBBAnimation-Info.plist ├── RBBAnimation-Prefix.pch ├── RBBAnimation.h ├── RBBAnimation.m ├── RBBBlockBasedArray.h ├── RBBBlockBasedArray.m ├── RBBCubicBezier.h ├── RBBCubicBezier.m ├── RBBCustomAnimation.h ├── RBBCustomAnimation.m ├── RBBEasingFunction.h ├── RBBEasingFunction.m ├── RBBLinearInterpolation.h ├── RBBLinearInterpolation.m ├── RBBSpringAnimation.h ├── RBBSpringAnimation.m ├── RBBTweenAnimation.h ├── RBBTweenAnimation.m ├── UIColor+PlatformIndependence.h └── UIColor+PlatformIndependence.m ├── RBBAnimationTest ├── CAAnimation+Name.h ├── CAAnimation+Name.m ├── Images.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── LaunchImage.launchimage │ │ └── Contents.json ├── RBBAnimationListViewController.h ├── RBBAnimationListViewController.m ├── RBBAnimationTest-Info.plist ├── RBBAnimationTest-Prefix.pch ├── RBBAnimationViewController.h ├── RBBAnimationViewController.m ├── RBBAppDelegate.h ├── RBBAppDelegate.m ├── en.lproj │ └── InfoPlist.strings └── main.m ├── README.md └── Specs ├── RBBBlockBasedArraySpec.m ├── RBBLinearInterpolationSpec.m ├── RBBSpringAnimationSpec.m └── Specs-Prefix.pch /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: robb 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | 3 | script: 4 | - xcodebuild -workspace RBBAnimation.xcworkspace -scheme "RBBAnimation iOS" test 5 | - xcodebuild -workspace RBBAnimation.xcworkspace -scheme "RBBAnimation Mac" test 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Robert Böhnke. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software is furnished to do so, 8 | subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | target 'RBBAnimationTest', :exclusive => true do 2 | platform :ios, '7.0' 3 | 4 | pod 'libextobjc/EXTScope', '0.4' 5 | pod 'libextobjc/EXTKeyPathCoding' 6 | pod 'libextobjc/EXTSynthesize' 7 | end 8 | 9 | target 'Specs-Mac', :exclusive => true do 10 | platform :osx, '10.8' 11 | 12 | pod 'Specta', '~> 0.2.1' 13 | pod 'Expecta', '0.3' 14 | end 15 | 16 | target 'Specs-iOS', :exclusive => true do 17 | platform :ios, '6.0' 18 | 19 | pod 'Specta', '~> 0.2.1' 20 | pod 'Expecta', '0.3' 21 | end 22 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Expecta (0.3.0) 3 | - libextobjc/EXTKeyPathCoding (0.4): 4 | - libextobjc/RuntimeExtensions 5 | - libextobjc/EXTScope (0.4): 6 | - libextobjc/RuntimeExtensions 7 | - libextobjc/EXTSynthesize (0.4): 8 | - libextobjc/RuntimeExtensions 9 | - libextobjc/RuntimeExtensions (0.4) 10 | - Specta (0.2.1) 11 | 12 | DEPENDENCIES: 13 | - Expecta (= 0.3) 14 | - libextobjc/EXTKeyPathCoding 15 | - libextobjc/EXTScope (= 0.4) 16 | - libextobjc/EXTSynthesize 17 | - Specta (~> 0.2.1) 18 | 19 | SPEC CHECKSUMS: 20 | Expecta: 917bda2935b63ca7175741b8cf1b26796db6205f 21 | libextobjc: f2802d4262f6885570df9799747409ceb1de602c 22 | Specta: 15a276a6343867b426d5ed135d5aa4d04123a573 23 | 24 | COCOAPODS: 0.37.2 25 | -------------------------------------------------------------------------------- /RBBAnimation.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "RBBAnimation" 3 | s.version = "0.4.0" 4 | s.summary = "Block-based animations made easy." 5 | s.description = <<-DESC 6 | RBBAnimation is a subclass of CAKeyframeAnimation that allows you to 7 | declare your animations using blocks instead of writing out all the 8 | individual key-frames. 9 | 10 | It also comes with a replacement for CASpringAnimation. 11 | DESC 12 | 13 | s.homepage = "https://github.com/robb/RBBAnimation" 14 | s.license = 'MIT' 15 | 16 | s.author = { "Robert Böhnke" => "robb@robb.is" } 17 | 18 | s.ios.deployment_target = '6.1' 19 | s.osx.deployment_target = '10.8' 20 | 21 | s.source = { :git => "https://github.com/robb/RBBAnimation.git", :tag => "v0.4.0" } 22 | 23 | s.source_files = 'RBBAnimation', 'RBBAnimation/**/*.{h,m}' 24 | s.ios.exclude_files = "RBBAnimation/NSColor+PlatformIndependence.{h,m}" 25 | s.osx.exclude_files = "RBBAnimation/UIColor+PlatformIndependence.{h,m}" 26 | 27 | s.framework = 'QuartzCore' 28 | s.requires_arc = true 29 | end 30 | -------------------------------------------------------------------------------- /RBBAnimation.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 540F65A318F81DC9005A6BB8 /* (null) in Resources */ = {isa = PBXBuildFile; }; 11 | 540F65A718F82347005A6BB8 /* NSValue+PlatformIndependence.h in Headers */ = {isa = PBXBuildFile; fileRef = 540F65A518F82347005A6BB8 /* NSValue+PlatformIndependence.h */; settings = {ATTRIBUTES = (Private, ); }; }; 12 | 540F65A818F82347005A6BB8 /* NSValue+PlatformIndependence.m in Sources */ = {isa = PBXBuildFile; fileRef = 540F65A618F82347005A6BB8 /* NSValue+PlatformIndependence.m */; }; 13 | 540F65A918F82347005A6BB8 /* NSValue+PlatformIndependence.m in Sources */ = {isa = PBXBuildFile; fileRef = 540F65A618F82347005A6BB8 /* NSValue+PlatformIndependence.m */; }; 14 | 540F65AB18F82B3E005A6BB8 /* RBBLinearInterpolationSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 540F65AA18F82B3E005A6BB8 /* RBBLinearInterpolationSpec.m */; }; 15 | 540F65AC18F82C67005A6BB8 /* RBBLinearInterpolationSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 540F65AA18F82B3E005A6BB8 /* RBBLinearInterpolationSpec.m */; }; 16 | 540F65AF18F83EB3005A6BB8 /* NSColor+PlatformIndependence.h in Headers */ = {isa = PBXBuildFile; fileRef = 540F65AD18F83EB3005A6BB8 /* NSColor+PlatformIndependence.h */; }; 17 | 540F65B018F83EB3005A6BB8 /* NSColor+PlatformIndependence.m in Sources */ = {isa = PBXBuildFile; fileRef = 540F65AE18F83EB3005A6BB8 /* NSColor+PlatformIndependence.m */; }; 18 | 540F65B318F83F98005A6BB8 /* UIColor+PlatformIndependence.m in Sources */ = {isa = PBXBuildFile; fileRef = 540F65B218F83F98005A6BB8 /* UIColor+PlatformIndependence.m */; }; 19 | 540F65B518F8407B005A6BB8 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 540F65B418F8407B005A6BB8 /* QuartzCore.framework */; }; 20 | 545D5AB6180AFCA500FC94AB /* CAAnimation+Name.m in Sources */ = {isa = PBXBuildFile; fileRef = 545D5AB3180AFCA500FC94AB /* CAAnimation+Name.m */; }; 21 | 545D5AB7180AFCA500FC94AB /* RBBAnimationListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 545D5AB5180AFCA500FC94AB /* RBBAnimationListViewController.m */; }; 22 | 545D5ABA180B1FAE00FC94AB /* RBBTweenAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = 545D5AB9180B1FAE00FC94AB /* RBBTweenAnimation.m */; }; 23 | 545D5ABC180B239000FC94AB /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 545D5ABB180B239000FC94AB /* UIKit.framework */; }; 24 | 545D5ABF180B2D3F00FC94AB /* RBBCubicBezier.m in Sources */ = {isa = PBXBuildFile; fileRef = 545D5ABE180B2D3F00FC94AB /* RBBCubicBezier.m */; }; 25 | 545D5AC2180B5E8400FC94AB /* RBBEasingFunction.m in Sources */ = {isa = PBXBuildFile; fileRef = 545D5AC1180B5E8400FC94AB /* RBBEasingFunction.m */; }; 26 | 545D5AC5180C138D00FC94AB /* RBBSpringAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = 545D5AC4180C138D00FC94AB /* RBBSpringAnimation.m */; }; 27 | 5466C56118082BEB00652BDC /* RBBBlockBasedArray.m in Sources */ = {isa = PBXBuildFile; fileRef = 5466C56018082BEB00652BDC /* RBBBlockBasedArray.m */; }; 28 | 5466C56318082D4200652BDC /* RBBBlockBasedArraySpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5466C56218082D4200652BDC /* RBBBlockBasedArraySpec.m */; }; 29 | 5466C569180849D100652BDC /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 54F3AE2D1807394800E1E688 /* Foundation.framework */; }; 30 | 5466C56B180849D100652BDC /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5466C56A180849D100652BDC /* CoreGraphics.framework */; }; 31 | 5466C56C180849D100652BDC /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 54F3AE3E1807394800E1E688 /* UIKit.framework */; }; 32 | 5466C572180849D200652BDC /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 5466C570180849D200652BDC /* InfoPlist.strings */; }; 33 | 5466C574180849D200652BDC /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 5466C573180849D200652BDC /* main.m */; }; 34 | 5466C578180849D200652BDC /* RBBAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 5466C577180849D200652BDC /* RBBAppDelegate.m */; }; 35 | 5466C57A180849D200652BDC /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5466C579180849D200652BDC /* Images.xcassets */; }; 36 | 5466C59518084B6A00652BDC /* libRBBAnimation iOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 54F3AE2A1807394800E1E688 /* libRBBAnimation iOS.a */; }; 37 | 5466C59818084BA200652BDC /* RBBAnimationViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 5466C59718084BA200652BDC /* RBBAnimationViewController.m */; }; 38 | 5479BEA4181D8008009811FD /* RBBCustomAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = 5479BEA3181D8008009811FD /* RBBCustomAnimation.m */; }; 39 | 549ECA8418F6ECFC00D968C7 /* RBBSpringAnimationSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 549ECA8318F6ECFC00D968C7 /* RBBSpringAnimationSpec.m */; }; 40 | 549ECA9618F814A000D968C7 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 549ECA9518F814A000D968C7 /* Cocoa.framework */; }; 41 | 549ECAAA18F814A000D968C7 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 54F3AE3B1807394800E1E688 /* XCTest.framework */; }; 42 | 549ECAAB18F814A000D968C7 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 549ECA9518F814A000D968C7 /* Cocoa.framework */; }; 43 | 549ECAAE18F814A000D968C7 /* RBBAnimation Mac.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 549ECA9418F814A000D968C7 /* RBBAnimation Mac.framework */; }; 44 | 549ECABD18F8155800D968C7 /* RBBBlockBasedArraySpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 5466C56218082D4200652BDC /* RBBBlockBasedArraySpec.m */; }; 45 | 549ECABE18F8155B00D968C7 /* RBBSpringAnimationSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = 549ECA8318F6ECFC00D968C7 /* RBBSpringAnimationSpec.m */; }; 46 | 549ECABF18F8157200D968C7 /* RBBAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = 54F3AE341807394800E1E688 /* RBBAnimation.m */; }; 47 | 549ECAC018F8157200D968C7 /* RBBCustomAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 5479BEA2181D8008009811FD /* RBBCustomAnimation.h */; settings = {ATTRIBUTES = (Public, ); }; }; 48 | 549ECAC118F8157200D968C7 /* RBBCustomAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = 5479BEA3181D8008009811FD /* RBBCustomAnimation.m */; }; 49 | 549ECAC218F8157200D968C7 /* RBBTweenAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 545D5AB8180B1FAE00FC94AB /* RBBTweenAnimation.h */; settings = {ATTRIBUTES = (Public, ); }; }; 50 | 549ECAC318F8157200D968C7 /* RBBTweenAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = 545D5AB9180B1FAE00FC94AB /* RBBTweenAnimation.m */; }; 51 | 549ECAC418F8157200D968C7 /* RBBSpringAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 545D5AC3180C138D00FC94AB /* RBBSpringAnimation.h */; settings = {ATTRIBUTES = (Public, ); }; }; 52 | 549ECAC518F8157200D968C7 /* RBBSpringAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = 545D5AC4180C138D00FC94AB /* RBBSpringAnimation.m */; }; 53 | 549ECAC618F8157200D968C7 /* RBBLinearInterpolation.h in Headers */ = {isa = PBXBuildFile; fileRef = 54D5EA87181AE8620014896C /* RBBLinearInterpolation.h */; settings = {ATTRIBUTES = (Private, ); }; }; 54 | 549ECAC718F8157200D968C7 /* RBBLinearInterpolation.m in Sources */ = {isa = PBXBuildFile; fileRef = 54D5EA88181AE8620014896C /* RBBLinearInterpolation.m */; }; 55 | 549ECAC818F8157200D968C7 /* RBBEasingFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = 545D5AC0180B5E8400FC94AB /* RBBEasingFunction.h */; settings = {ATTRIBUTES = (Public, ); }; }; 56 | 549ECAC918F8157200D968C7 /* RBBEasingFunction.m in Sources */ = {isa = PBXBuildFile; fileRef = 545D5AC1180B5E8400FC94AB /* RBBEasingFunction.m */; }; 57 | 549ECACA18F8157200D968C7 /* RBBCubicBezier.h in Headers */ = {isa = PBXBuildFile; fileRef = 545D5ABD180B2D3F00FC94AB /* RBBCubicBezier.h */; settings = {ATTRIBUTES = (Public, ); }; }; 58 | 549ECACB18F8157200D968C7 /* RBBCubicBezier.m in Sources */ = {isa = PBXBuildFile; fileRef = 545D5ABE180B2D3F00FC94AB /* RBBCubicBezier.m */; }; 59 | 549ECACC18F8157200D968C7 /* RBBBlockBasedArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 5466C55F18082BEB00652BDC /* RBBBlockBasedArray.h */; settings = {ATTRIBUTES = (Private, ); }; }; 60 | 549ECACD18F8157200D968C7 /* RBBBlockBasedArray.m in Sources */ = {isa = PBXBuildFile; fileRef = 5466C56018082BEB00652BDC /* RBBBlockBasedArray.m */; }; 61 | 549ECACE18F8157500D968C7 /* RBBAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 54F3AE321807394800E1E688 /* RBBAnimation.h */; settings = {ATTRIBUTES = (Public, ); }; }; 62 | 54D5EA89181AE8620014896C /* RBBLinearInterpolation.m in Sources */ = {isa = PBXBuildFile; fileRef = 54D5EA88181AE8620014896C /* RBBLinearInterpolation.m */; }; 63 | 54F3AE2E1807394800E1E688 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 54F3AE2D1807394800E1E688 /* Foundation.framework */; }; 64 | 54F3AE331807394800E1E688 /* RBBAnimation.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 54F3AE321807394800E1E688 /* RBBAnimation.h */; }; 65 | 54F3AE351807394800E1E688 /* RBBAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = 54F3AE341807394800E1E688 /* RBBAnimation.m */; }; 66 | 54F3AE3C1807394800E1E688 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 54F3AE3B1807394800E1E688 /* XCTest.framework */; }; 67 | 54F3AE3D1807394800E1E688 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 54F3AE2D1807394800E1E688 /* Foundation.framework */; }; 68 | 54F3AE3F1807394800E1E688 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 54F3AE3E1807394800E1E688 /* UIKit.framework */; }; 69 | 54F3AE421807394800E1E688 /* libRBBAnimation iOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 54F3AE2A1807394800E1E688 /* libRBBAnimation iOS.a */; }; 70 | 6439C0B3C2C941869D563894 /* libPods-RBBAnimationTest.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9764F4EDA8D64676ADE7428E /* libPods-RBBAnimationTest.a */; }; 71 | 88D1CBC6B26446F4BE5A393F /* libPods-Specs-Mac.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E856D162B1FB41A29C1DD243 /* libPods-Specs-Mac.a */; }; 72 | CA49CA861D544AAD806A9A8B /* libPods-Specs-iOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = A1C7CF8386EA4D9896C0AD15 /* libPods-Specs-iOS.a */; }; 73 | /* End PBXBuildFile section */ 74 | 75 | /* Begin PBXContainerItemProxy section */ 76 | 5466C59318084B6400652BDC /* PBXContainerItemProxy */ = { 77 | isa = PBXContainerItemProxy; 78 | containerPortal = 54F3AE221807394800E1E688 /* Project object */; 79 | proxyType = 1; 80 | remoteGlobalIDString = 54F3AE291807394800E1E688; 81 | remoteInfo = RBBAnimation; 82 | }; 83 | 549ECAAC18F814A000D968C7 /* PBXContainerItemProxy */ = { 84 | isa = PBXContainerItemProxy; 85 | containerPortal = 54F3AE221807394800E1E688 /* Project object */; 86 | proxyType = 1; 87 | remoteGlobalIDString = 549ECA9318F814A000D968C7; 88 | remoteInfo = "RBBAnimation Mac"; 89 | }; 90 | 54F3AE401807394800E1E688 /* PBXContainerItemProxy */ = { 91 | isa = PBXContainerItemProxy; 92 | containerPortal = 54F3AE221807394800E1E688 /* Project object */; 93 | proxyType = 1; 94 | remoteGlobalIDString = 54F3AE291807394800E1E688; 95 | remoteInfo = RBBAnimation; 96 | }; 97 | /* End PBXContainerItemProxy section */ 98 | 99 | /* Begin PBXCopyFilesBuildPhase section */ 100 | 54F3AE281807394800E1E688 /* CopyFiles */ = { 101 | isa = PBXCopyFilesBuildPhase; 102 | buildActionMask = 2147483647; 103 | dstPath = "include/$(PRODUCT_NAME)"; 104 | dstSubfolderSpec = 16; 105 | files = ( 106 | 54F3AE331807394800E1E688 /* RBBAnimation.h in CopyFiles */, 107 | ); 108 | runOnlyForDeploymentPostprocessing = 0; 109 | }; 110 | /* End PBXCopyFilesBuildPhase section */ 111 | 112 | /* Begin PBXFileReference section */ 113 | 288615584456976E0663A0C5 /* Pods-RBBAnimationTest.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RBBAnimationTest.release.xcconfig"; path = "Pods/Target Support Files/Pods-RBBAnimationTest/Pods-RBBAnimationTest.release.xcconfig"; sourceTree = ""; }; 114 | 3E441AF5FD5F61A5ACBC325F /* Pods-Specs-Mac.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Specs-Mac.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Specs-Mac/Pods-Specs-Mac.debug.xcconfig"; sourceTree = ""; }; 115 | 540F65A018F8188F005A6BB8 /* RBBAnimation-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "RBBAnimation-Info.plist"; sourceTree = ""; }; 116 | 540F65A518F82347005A6BB8 /* NSValue+PlatformIndependence.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSValue+PlatformIndependence.h"; sourceTree = ""; }; 117 | 540F65A618F82347005A6BB8 /* NSValue+PlatformIndependence.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSValue+PlatformIndependence.m"; sourceTree = ""; }; 118 | 540F65AA18F82B3E005A6BB8 /* RBBLinearInterpolationSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RBBLinearInterpolationSpec.m; sourceTree = ""; }; 119 | 540F65AD18F83EB3005A6BB8 /* NSColor+PlatformIndependence.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSColor+PlatformIndependence.h"; sourceTree = ""; }; 120 | 540F65AE18F83EB3005A6BB8 /* NSColor+PlatformIndependence.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSColor+PlatformIndependence.m"; sourceTree = ""; }; 121 | 540F65B118F83F98005A6BB8 /* UIColor+PlatformIndependence.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIColor+PlatformIndependence.h"; sourceTree = ""; }; 122 | 540F65B218F83F98005A6BB8 /* UIColor+PlatformIndependence.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIColor+PlatformIndependence.m"; sourceTree = ""; }; 123 | 540F65B418F8407B005A6BB8 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk/System/Library/Frameworks/QuartzCore.framework; sourceTree = DEVELOPER_DIR; }; 124 | 545D5AB2180AFCA500FC94AB /* CAAnimation+Name.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CAAnimation+Name.h"; sourceTree = ""; }; 125 | 545D5AB3180AFCA500FC94AB /* CAAnimation+Name.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "CAAnimation+Name.m"; sourceTree = ""; }; 126 | 545D5AB4180AFCA500FC94AB /* RBBAnimationListViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RBBAnimationListViewController.h; sourceTree = ""; }; 127 | 545D5AB5180AFCA500FC94AB /* RBBAnimationListViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RBBAnimationListViewController.m; sourceTree = ""; }; 128 | 545D5AB8180B1FAE00FC94AB /* RBBTweenAnimation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RBBTweenAnimation.h; sourceTree = ""; }; 129 | 545D5AB9180B1FAE00FC94AB /* RBBTweenAnimation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RBBTweenAnimation.m; sourceTree = ""; }; 130 | 545D5ABB180B239000FC94AB /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 131 | 545D5ABD180B2D3F00FC94AB /* RBBCubicBezier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RBBCubicBezier.h; sourceTree = ""; }; 132 | 545D5ABE180B2D3F00FC94AB /* RBBCubicBezier.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RBBCubicBezier.m; sourceTree = ""; }; 133 | 545D5AC0180B5E8400FC94AB /* RBBEasingFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RBBEasingFunction.h; sourceTree = ""; }; 134 | 545D5AC1180B5E8400FC94AB /* RBBEasingFunction.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RBBEasingFunction.m; sourceTree = ""; }; 135 | 545D5AC3180C138D00FC94AB /* RBBSpringAnimation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RBBSpringAnimation.h; sourceTree = ""; }; 136 | 545D5AC4180C138D00FC94AB /* RBBSpringAnimation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RBBSpringAnimation.m; sourceTree = ""; }; 137 | 5466C55F18082BEB00652BDC /* RBBBlockBasedArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RBBBlockBasedArray.h; sourceTree = ""; }; 138 | 5466C56018082BEB00652BDC /* RBBBlockBasedArray.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RBBBlockBasedArray.m; sourceTree = ""; }; 139 | 5466C56218082D4200652BDC /* RBBBlockBasedArraySpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RBBBlockBasedArraySpec.m; sourceTree = ""; }; 140 | 5466C568180849D100652BDC /* RBBAnimationTest.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = RBBAnimationTest.app; sourceTree = BUILT_PRODUCTS_DIR; }; 141 | 5466C56A180849D100652BDC /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 142 | 5466C56F180849D200652BDC /* RBBAnimationTest-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "RBBAnimationTest-Info.plist"; sourceTree = ""; }; 143 | 5466C571180849D200652BDC /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 144 | 5466C573180849D200652BDC /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 145 | 5466C575180849D200652BDC /* RBBAnimationTest-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RBBAnimationTest-Prefix.pch"; sourceTree = ""; }; 146 | 5466C576180849D200652BDC /* RBBAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RBBAppDelegate.h; sourceTree = ""; }; 147 | 5466C577180849D200652BDC /* RBBAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RBBAppDelegate.m; sourceTree = ""; }; 148 | 5466C579180849D200652BDC /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 149 | 5466C59618084BA200652BDC /* RBBAnimationViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RBBAnimationViewController.h; sourceTree = ""; }; 150 | 5466C59718084BA200652BDC /* RBBAnimationViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RBBAnimationViewController.m; sourceTree = ""; }; 151 | 5479BEA2181D8008009811FD /* RBBCustomAnimation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RBBCustomAnimation.h; sourceTree = ""; }; 152 | 5479BEA3181D8008009811FD /* RBBCustomAnimation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RBBCustomAnimation.m; sourceTree = ""; }; 153 | 549ECA8318F6ECFC00D968C7 /* RBBSpringAnimationSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RBBSpringAnimationSpec.m; sourceTree = ""; }; 154 | 549ECA9418F814A000D968C7 /* RBBAnimation Mac.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = "RBBAnimation Mac.framework"; sourceTree = BUILT_PRODUCTS_DIR; }; 155 | 549ECA9518F814A000D968C7 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = Library/Frameworks/Cocoa.framework; sourceTree = DEVELOPER_DIR; }; 156 | 549ECA9818F814A000D968C7 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 157 | 549ECA9918F814A000D968C7 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; 158 | 549ECA9A18F814A000D968C7 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; 159 | 549ECAA918F814A000D968C7 /* Specs-Mac.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Specs-Mac.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 160 | 54D5EA87181AE8620014896C /* RBBLinearInterpolation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RBBLinearInterpolation.h; sourceTree = ""; }; 161 | 54D5EA88181AE8620014896C /* RBBLinearInterpolation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RBBLinearInterpolation.m; sourceTree = ""; }; 162 | 54F3AE2A1807394800E1E688 /* libRBBAnimation iOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libRBBAnimation iOS.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 163 | 54F3AE2D1807394800E1E688 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 164 | 54F3AE311807394800E1E688 /* RBBAnimation-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "RBBAnimation-Prefix.pch"; sourceTree = ""; }; 165 | 54F3AE321807394800E1E688 /* RBBAnimation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RBBAnimation.h; sourceTree = ""; }; 166 | 54F3AE341807394800E1E688 /* RBBAnimation.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RBBAnimation.m; sourceTree = ""; }; 167 | 54F3AE3A1807394800E1E688 /* Specs-iOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Specs-iOS.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 168 | 54F3AE3B1807394800E1E688 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 169 | 54F3AE3E1807394800E1E688 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; }; 170 | 54F3AE5318073A1900E1E688 /* Specs-Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Specs-Prefix.pch"; sourceTree = ""; }; 171 | 74ABD43AFADA521EF3D0EC21 /* Pods-Specs-iOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Specs-iOS.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Specs-iOS/Pods-Specs-iOS.debug.xcconfig"; sourceTree = ""; }; 172 | 7582873345F4B52FF68854CB /* Pods-Specs-iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Specs-iOS.release.xcconfig"; path = "Pods/Target Support Files/Pods-Specs-iOS/Pods-Specs-iOS.release.xcconfig"; sourceTree = ""; }; 173 | 9764F4EDA8D64676ADE7428E /* libPods-RBBAnimationTest.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-RBBAnimationTest.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 174 | A1C7CF8386EA4D9896C0AD15 /* libPods-Specs-iOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Specs-iOS.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 175 | D2A7704395D460556362784E /* Pods-Specs-Mac.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Specs-Mac.release.xcconfig"; path = "Pods/Target Support Files/Pods-Specs-Mac/Pods-Specs-Mac.release.xcconfig"; sourceTree = ""; }; 176 | E856D162B1FB41A29C1DD243 /* libPods-Specs-Mac.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Specs-Mac.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 177 | ED73BC249900E38EB30B303F /* Pods-RBBAnimationTest.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RBBAnimationTest.debug.xcconfig"; path = "Pods/Target Support Files/Pods-RBBAnimationTest/Pods-RBBAnimationTest.debug.xcconfig"; sourceTree = ""; }; 178 | FD960C698C3E4DB198BD591C /* libPods-Specs.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Specs.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 179 | /* End PBXFileReference section */ 180 | 181 | /* Begin PBXFrameworksBuildPhase section */ 182 | 5466C565180849D100652BDC /* Frameworks */ = { 183 | isa = PBXFrameworksBuildPhase; 184 | buildActionMask = 2147483647; 185 | files = ( 186 | 5466C59518084B6A00652BDC /* libRBBAnimation iOS.a in Frameworks */, 187 | 5466C56B180849D100652BDC /* CoreGraphics.framework in Frameworks */, 188 | 5466C56C180849D100652BDC /* UIKit.framework in Frameworks */, 189 | 5466C569180849D100652BDC /* Foundation.framework in Frameworks */, 190 | 6439C0B3C2C941869D563894 /* libPods-RBBAnimationTest.a in Frameworks */, 191 | ); 192 | runOnlyForDeploymentPostprocessing = 0; 193 | }; 194 | 549ECA9018F814A000D968C7 /* Frameworks */ = { 195 | isa = PBXFrameworksBuildPhase; 196 | buildActionMask = 2147483647; 197 | files = ( 198 | 540F65B518F8407B005A6BB8 /* QuartzCore.framework in Frameworks */, 199 | 549ECA9618F814A000D968C7 /* Cocoa.framework in Frameworks */, 200 | ); 201 | runOnlyForDeploymentPostprocessing = 0; 202 | }; 203 | 549ECAA618F814A000D968C7 /* Frameworks */ = { 204 | isa = PBXFrameworksBuildPhase; 205 | buildActionMask = 2147483647; 206 | files = ( 207 | 549ECAAE18F814A000D968C7 /* RBBAnimation Mac.framework in Frameworks */, 208 | 549ECAAB18F814A000D968C7 /* Cocoa.framework in Frameworks */, 209 | 549ECAAA18F814A000D968C7 /* XCTest.framework in Frameworks */, 210 | 88D1CBC6B26446F4BE5A393F /* libPods-Specs-Mac.a in Frameworks */, 211 | ); 212 | runOnlyForDeploymentPostprocessing = 0; 213 | }; 214 | 54F3AE271807394800E1E688 /* Frameworks */ = { 215 | isa = PBXFrameworksBuildPhase; 216 | buildActionMask = 2147483647; 217 | files = ( 218 | 545D5ABC180B239000FC94AB /* UIKit.framework in Frameworks */, 219 | 54F3AE2E1807394800E1E688 /* Foundation.framework in Frameworks */, 220 | ); 221 | runOnlyForDeploymentPostprocessing = 0; 222 | }; 223 | 54F3AE371807394800E1E688 /* Frameworks */ = { 224 | isa = PBXFrameworksBuildPhase; 225 | buildActionMask = 2147483647; 226 | files = ( 227 | 54F3AE3C1807394800E1E688 /* XCTest.framework in Frameworks */, 228 | 54F3AE421807394800E1E688 /* libRBBAnimation iOS.a in Frameworks */, 229 | 54F3AE3F1807394800E1E688 /* UIKit.framework in Frameworks */, 230 | 54F3AE3D1807394800E1E688 /* Foundation.framework in Frameworks */, 231 | CA49CA861D544AAD806A9A8B /* libPods-Specs-iOS.a in Frameworks */, 232 | ); 233 | runOnlyForDeploymentPostprocessing = 0; 234 | }; 235 | /* End PBXFrameworksBuildPhase section */ 236 | 237 | /* Begin PBXGroup section */ 238 | 5466C56D180849D200652BDC /* RBBAnimationTest */ = { 239 | isa = PBXGroup; 240 | children = ( 241 | 5466C576180849D200652BDC /* RBBAppDelegate.h */, 242 | 5466C577180849D200652BDC /* RBBAppDelegate.m */, 243 | 545D5AB2180AFCA500FC94AB /* CAAnimation+Name.h */, 244 | 545D5AB3180AFCA500FC94AB /* CAAnimation+Name.m */, 245 | 545D5AB4180AFCA500FC94AB /* RBBAnimationListViewController.h */, 246 | 545D5AB5180AFCA500FC94AB /* RBBAnimationListViewController.m */, 247 | 5466C59618084BA200652BDC /* RBBAnimationViewController.h */, 248 | 5466C59718084BA200652BDC /* RBBAnimationViewController.m */, 249 | 5466C579180849D200652BDC /* Images.xcassets */, 250 | 5466C56E180849D200652BDC /* Supporting Files */, 251 | ); 252 | path = RBBAnimationTest; 253 | sourceTree = ""; 254 | }; 255 | 5466C56E180849D200652BDC /* Supporting Files */ = { 256 | isa = PBXGroup; 257 | children = ( 258 | 5466C56F180849D200652BDC /* RBBAnimationTest-Info.plist */, 259 | 5466C570180849D200652BDC /* InfoPlist.strings */, 260 | 5466C573180849D200652BDC /* main.m */, 261 | 5466C575180849D200652BDC /* RBBAnimationTest-Prefix.pch */, 262 | ); 263 | name = "Supporting Files"; 264 | sourceTree = ""; 265 | }; 266 | 549ECA9718F814A000D968C7 /* Other Frameworks */ = { 267 | isa = PBXGroup; 268 | children = ( 269 | 549ECA9818F814A000D968C7 /* Foundation.framework */, 270 | 549ECA9918F814A000D968C7 /* CoreData.framework */, 271 | 549ECA9A18F814A000D968C7 /* AppKit.framework */, 272 | ); 273 | name = "Other Frameworks"; 274 | sourceTree = ""; 275 | }; 276 | 54F3AE211807394800E1E688 = { 277 | isa = PBXGroup; 278 | children = ( 279 | 54F3AE2F1807394800E1E688 /* RBBAnimation */, 280 | 54F3AE431807394800E1E688 /* Specs */, 281 | 5466C56D180849D200652BDC /* RBBAnimationTest */, 282 | 54F3AE2C1807394800E1E688 /* Frameworks */, 283 | 54F3AE2B1807394800E1E688 /* Products */, 284 | AF8189F9DF1EC1EA504BCBB0 /* Pods */, 285 | ); 286 | sourceTree = ""; 287 | }; 288 | 54F3AE2B1807394800E1E688 /* Products */ = { 289 | isa = PBXGroup; 290 | children = ( 291 | 54F3AE2A1807394800E1E688 /* libRBBAnimation iOS.a */, 292 | 54F3AE3A1807394800E1E688 /* Specs-iOS.xctest */, 293 | 5466C568180849D100652BDC /* RBBAnimationTest.app */, 294 | 549ECA9418F814A000D968C7 /* RBBAnimation Mac.framework */, 295 | 549ECAA918F814A000D968C7 /* Specs-Mac.xctest */, 296 | ); 297 | name = Products; 298 | sourceTree = ""; 299 | }; 300 | 54F3AE2C1807394800E1E688 /* Frameworks */ = { 301 | isa = PBXGroup; 302 | children = ( 303 | 540F65B418F8407B005A6BB8 /* QuartzCore.framework */, 304 | 545D5ABB180B239000FC94AB /* UIKit.framework */, 305 | 54F3AE2D1807394800E1E688 /* Foundation.framework */, 306 | 54F3AE3B1807394800E1E688 /* XCTest.framework */, 307 | 54F3AE3E1807394800E1E688 /* UIKit.framework */, 308 | FD960C698C3E4DB198BD591C /* libPods-Specs.a */, 309 | 5466C56A180849D100652BDC /* CoreGraphics.framework */, 310 | 9764F4EDA8D64676ADE7428E /* libPods-RBBAnimationTest.a */, 311 | 549ECA9518F814A000D968C7 /* Cocoa.framework */, 312 | 549ECA9718F814A000D968C7 /* Other Frameworks */, 313 | E856D162B1FB41A29C1DD243 /* libPods-Specs-Mac.a */, 314 | A1C7CF8386EA4D9896C0AD15 /* libPods-Specs-iOS.a */, 315 | ); 316 | name = Frameworks; 317 | sourceTree = ""; 318 | }; 319 | 54F3AE2F1807394800E1E688 /* RBBAnimation */ = { 320 | isa = PBXGroup; 321 | children = ( 322 | 54F3AE321807394800E1E688 /* RBBAnimation.h */, 323 | 54F3AE341807394800E1E688 /* RBBAnimation.m */, 324 | 5479BEA2181D8008009811FD /* RBBCustomAnimation.h */, 325 | 5479BEA3181D8008009811FD /* RBBCustomAnimation.m */, 326 | 545D5AB8180B1FAE00FC94AB /* RBBTweenAnimation.h */, 327 | 545D5AB9180B1FAE00FC94AB /* RBBTweenAnimation.m */, 328 | 545D5AC3180C138D00FC94AB /* RBBSpringAnimation.h */, 329 | 545D5AC4180C138D00FC94AB /* RBBSpringAnimation.m */, 330 | 54D5EA87181AE8620014896C /* RBBLinearInterpolation.h */, 331 | 54D5EA88181AE8620014896C /* RBBLinearInterpolation.m */, 332 | 545D5AC0180B5E8400FC94AB /* RBBEasingFunction.h */, 333 | 545D5AC1180B5E8400FC94AB /* RBBEasingFunction.m */, 334 | 545D5ABD180B2D3F00FC94AB /* RBBCubicBezier.h */, 335 | 545D5ABE180B2D3F00FC94AB /* RBBCubicBezier.m */, 336 | 5466C55F18082BEB00652BDC /* RBBBlockBasedArray.h */, 337 | 5466C56018082BEB00652BDC /* RBBBlockBasedArray.m */, 338 | 540F65A518F82347005A6BB8 /* NSValue+PlatformIndependence.h */, 339 | 540F65A618F82347005A6BB8 /* NSValue+PlatformIndependence.m */, 340 | 540F65AD18F83EB3005A6BB8 /* NSColor+PlatformIndependence.h */, 341 | 540F65AE18F83EB3005A6BB8 /* NSColor+PlatformIndependence.m */, 342 | 540F65B118F83F98005A6BB8 /* UIColor+PlatformIndependence.h */, 343 | 540F65B218F83F98005A6BB8 /* UIColor+PlatformIndependence.m */, 344 | 54F3AE301807394800E1E688 /* Supporting Files */, 345 | ); 346 | path = RBBAnimation; 347 | sourceTree = ""; 348 | }; 349 | 54F3AE301807394800E1E688 /* Supporting Files */ = { 350 | isa = PBXGroup; 351 | children = ( 352 | 54F3AE311807394800E1E688 /* RBBAnimation-Prefix.pch */, 353 | 540F65A018F8188F005A6BB8 /* RBBAnimation-Info.plist */, 354 | ); 355 | name = "Supporting Files"; 356 | sourceTree = ""; 357 | }; 358 | 54F3AE431807394800E1E688 /* Specs */ = { 359 | isa = PBXGroup; 360 | children = ( 361 | 5466C56218082D4200652BDC /* RBBBlockBasedArraySpec.m */, 362 | 540F65AA18F82B3E005A6BB8 /* RBBLinearInterpolationSpec.m */, 363 | 549ECA8318F6ECFC00D968C7 /* RBBSpringAnimationSpec.m */, 364 | 54F3AE441807394800E1E688 /* Supporting Files */, 365 | ); 366 | path = Specs; 367 | sourceTree = ""; 368 | }; 369 | 54F3AE441807394800E1E688 /* Supporting Files */ = { 370 | isa = PBXGroup; 371 | children = ( 372 | 54F3AE5318073A1900E1E688 /* Specs-Prefix.pch */, 373 | ); 374 | name = "Supporting Files"; 375 | sourceTree = ""; 376 | }; 377 | AF8189F9DF1EC1EA504BCBB0 /* Pods */ = { 378 | isa = PBXGroup; 379 | children = ( 380 | ED73BC249900E38EB30B303F /* Pods-RBBAnimationTest.debug.xcconfig */, 381 | 288615584456976E0663A0C5 /* Pods-RBBAnimationTest.release.xcconfig */, 382 | 3E441AF5FD5F61A5ACBC325F /* Pods-Specs-Mac.debug.xcconfig */, 383 | D2A7704395D460556362784E /* Pods-Specs-Mac.release.xcconfig */, 384 | 74ABD43AFADA521EF3D0EC21 /* Pods-Specs-iOS.debug.xcconfig */, 385 | 7582873345F4B52FF68854CB /* Pods-Specs-iOS.release.xcconfig */, 386 | ); 387 | name = Pods; 388 | sourceTree = ""; 389 | }; 390 | /* End PBXGroup section */ 391 | 392 | /* Begin PBXHeadersBuildPhase section */ 393 | 549ECA9118F814A000D968C7 /* Headers */ = { 394 | isa = PBXHeadersBuildPhase; 395 | buildActionMask = 2147483647; 396 | files = ( 397 | 549ECAC218F8157200D968C7 /* RBBTweenAnimation.h in Headers */, 398 | 549ECAC818F8157200D968C7 /* RBBEasingFunction.h in Headers */, 399 | 549ECACE18F8157500D968C7 /* RBBAnimation.h in Headers */, 400 | 549ECAC418F8157200D968C7 /* RBBSpringAnimation.h in Headers */, 401 | 549ECACA18F8157200D968C7 /* RBBCubicBezier.h in Headers */, 402 | 549ECAC018F8157200D968C7 /* RBBCustomAnimation.h in Headers */, 403 | 549ECAC618F8157200D968C7 /* RBBLinearInterpolation.h in Headers */, 404 | 540F65A718F82347005A6BB8 /* NSValue+PlatformIndependence.h in Headers */, 405 | 540F65AF18F83EB3005A6BB8 /* NSColor+PlatformIndependence.h in Headers */, 406 | 549ECACC18F8157200D968C7 /* RBBBlockBasedArray.h in Headers */, 407 | ); 408 | runOnlyForDeploymentPostprocessing = 0; 409 | }; 410 | /* End PBXHeadersBuildPhase section */ 411 | 412 | /* Begin PBXNativeTarget section */ 413 | 5466C567180849D100652BDC /* RBBAnimationTest */ = { 414 | isa = PBXNativeTarget; 415 | buildConfigurationList = 5466C58D180849D200652BDC /* Build configuration list for PBXNativeTarget "RBBAnimationTest" */; 416 | buildPhases = ( 417 | 06184DDF10714481847B6FA6 /* Check Pods Manifest.lock */, 418 | 5466C564180849D100652BDC /* Sources */, 419 | 5466C565180849D100652BDC /* Frameworks */, 420 | 5466C566180849D100652BDC /* Resources */, 421 | A5CEBE251F3B4BF0A09218AC /* Copy Pods Resources */, 422 | ); 423 | buildRules = ( 424 | ); 425 | dependencies = ( 426 | 5466C59418084B6400652BDC /* PBXTargetDependency */, 427 | ); 428 | name = RBBAnimationTest; 429 | productName = RBBAnimationTest; 430 | productReference = 5466C568180849D100652BDC /* RBBAnimationTest.app */; 431 | productType = "com.apple.product-type.application"; 432 | }; 433 | 549ECA9318F814A000D968C7 /* RBBAnimation Mac */ = { 434 | isa = PBXNativeTarget; 435 | buildConfigurationList = 549ECAB718F814A000D968C7 /* Build configuration list for PBXNativeTarget "RBBAnimation Mac" */; 436 | buildPhases = ( 437 | 549ECA8F18F814A000D968C7 /* Sources */, 438 | 549ECA9018F814A000D968C7 /* Frameworks */, 439 | 549ECA9118F814A000D968C7 /* Headers */, 440 | 549ECA9218F814A000D968C7 /* Resources */, 441 | ); 442 | buildRules = ( 443 | ); 444 | dependencies = ( 445 | ); 446 | name = "RBBAnimation Mac"; 447 | productName = "RBBAnimation Mac"; 448 | productReference = 549ECA9418F814A000D968C7 /* RBBAnimation Mac.framework */; 449 | productType = "com.apple.product-type.framework"; 450 | }; 451 | 549ECAA818F814A000D968C7 /* Specs-Mac */ = { 452 | isa = PBXNativeTarget; 453 | buildConfigurationList = 549ECABA18F814A000D968C7 /* Build configuration list for PBXNativeTarget "Specs-Mac" */; 454 | buildPhases = ( 455 | 7854BEC60F31406CA9C284E7 /* Check Pods Manifest.lock */, 456 | 549ECAA518F814A000D968C7 /* Sources */, 457 | 549ECAA618F814A000D968C7 /* Frameworks */, 458 | 549ECAA718F814A000D968C7 /* Resources */, 459 | 95F54BF0BB504B1783E7A15E /* Copy Pods Resources */, 460 | ); 461 | buildRules = ( 462 | ); 463 | dependencies = ( 464 | 549ECAAD18F814A000D968C7 /* PBXTargetDependency */, 465 | ); 466 | name = "Specs-Mac"; 467 | productName = "RBBAnimation MacTests"; 468 | productReference = 549ECAA918F814A000D968C7 /* Specs-Mac.xctest */; 469 | productType = "com.apple.product-type.bundle.unit-test"; 470 | }; 471 | 54F3AE291807394800E1E688 /* RBBAnimation iOS */ = { 472 | isa = PBXNativeTarget; 473 | buildConfigurationList = 54F3AE4D1807394800E1E688 /* Build configuration list for PBXNativeTarget "RBBAnimation iOS" */; 474 | buildPhases = ( 475 | 54F3AE261807394800E1E688 /* Sources */, 476 | 54F3AE271807394800E1E688 /* Frameworks */, 477 | 54F3AE281807394800E1E688 /* CopyFiles */, 478 | ); 479 | buildRules = ( 480 | ); 481 | dependencies = ( 482 | ); 483 | name = "RBBAnimation iOS"; 484 | productName = RBBAnimation; 485 | productReference = 54F3AE2A1807394800E1E688 /* libRBBAnimation iOS.a */; 486 | productType = "com.apple.product-type.library.static"; 487 | }; 488 | 54F3AE391807394800E1E688 /* Specs-iOS */ = { 489 | isa = PBXNativeTarget; 490 | buildConfigurationList = 54F3AE501807394800E1E688 /* Build configuration list for PBXNativeTarget "Specs-iOS" */; 491 | buildPhases = ( 492 | 8F58412594AB4B62BD72EB53 /* Check Pods Manifest.lock */, 493 | 54F3AE361807394800E1E688 /* Sources */, 494 | 54F3AE371807394800E1E688 /* Frameworks */, 495 | 54F3AE381807394800E1E688 /* Resources */, 496 | 80B0D276277B4291ABDAD6CF /* Copy Pods Resources */, 497 | 54F3AE5618082AE400E1E688 /* ShellScript */, 498 | ); 499 | buildRules = ( 500 | ); 501 | dependencies = ( 502 | 54F3AE411807394800E1E688 /* PBXTargetDependency */, 503 | ); 504 | name = "Specs-iOS"; 505 | productName = Specs; 506 | productReference = 54F3AE3A1807394800E1E688 /* Specs-iOS.xctest */; 507 | productType = "com.apple.product-type.bundle.unit-test"; 508 | }; 509 | /* End PBXNativeTarget section */ 510 | 511 | /* Begin PBXProject section */ 512 | 54F3AE221807394800E1E688 /* Project object */ = { 513 | isa = PBXProject; 514 | attributes = { 515 | LastUpgradeCheck = 0510; 516 | ORGANIZATIONNAME = "Robert Böhnke"; 517 | TargetAttributes = { 518 | 549ECAA818F814A000D968C7 = { 519 | TestTargetID = 549ECA9318F814A000D968C7; 520 | }; 521 | 54F3AE391807394800E1E688 = { 522 | TestTargetID = 54F3AE291807394800E1E688; 523 | }; 524 | }; 525 | }; 526 | buildConfigurationList = 54F3AE251807394800E1E688 /* Build configuration list for PBXProject "RBBAnimation" */; 527 | compatibilityVersion = "Xcode 3.2"; 528 | developmentRegion = English; 529 | hasScannedForEncodings = 0; 530 | knownRegions = ( 531 | en, 532 | ); 533 | mainGroup = 54F3AE211807394800E1E688; 534 | productRefGroup = 54F3AE2B1807394800E1E688 /* Products */; 535 | projectDirPath = ""; 536 | projectRoot = ""; 537 | targets = ( 538 | 54F3AE291807394800E1E688 /* RBBAnimation iOS */, 539 | 54F3AE391807394800E1E688 /* Specs-iOS */, 540 | 549ECA9318F814A000D968C7 /* RBBAnimation Mac */, 541 | 549ECAA818F814A000D968C7 /* Specs-Mac */, 542 | 5466C567180849D100652BDC /* RBBAnimationTest */, 543 | ); 544 | }; 545 | /* End PBXProject section */ 546 | 547 | /* Begin PBXResourcesBuildPhase section */ 548 | 5466C566180849D100652BDC /* Resources */ = { 549 | isa = PBXResourcesBuildPhase; 550 | buildActionMask = 2147483647; 551 | files = ( 552 | 5466C572180849D200652BDC /* InfoPlist.strings in Resources */, 553 | 5466C57A180849D200652BDC /* Images.xcassets in Resources */, 554 | ); 555 | runOnlyForDeploymentPostprocessing = 0; 556 | }; 557 | 549ECA9218F814A000D968C7 /* Resources */ = { 558 | isa = PBXResourcesBuildPhase; 559 | buildActionMask = 2147483647; 560 | files = ( 561 | ); 562 | runOnlyForDeploymentPostprocessing = 0; 563 | }; 564 | 549ECAA718F814A000D968C7 /* Resources */ = { 565 | isa = PBXResourcesBuildPhase; 566 | buildActionMask = 2147483647; 567 | files = ( 568 | ); 569 | runOnlyForDeploymentPostprocessing = 0; 570 | }; 571 | 54F3AE381807394800E1E688 /* Resources */ = { 572 | isa = PBXResourcesBuildPhase; 573 | buildActionMask = 2147483647; 574 | files = ( 575 | 540F65A318F81DC9005A6BB8 /* (null) in Resources */, 576 | ); 577 | runOnlyForDeploymentPostprocessing = 0; 578 | }; 579 | /* End PBXResourcesBuildPhase section */ 580 | 581 | /* Begin PBXShellScriptBuildPhase section */ 582 | 06184DDF10714481847B6FA6 /* Check Pods Manifest.lock */ = { 583 | isa = PBXShellScriptBuildPhase; 584 | buildActionMask = 2147483647; 585 | files = ( 586 | ); 587 | inputPaths = ( 588 | ); 589 | name = "Check Pods Manifest.lock"; 590 | outputPaths = ( 591 | ); 592 | runOnlyForDeploymentPostprocessing = 0; 593 | shellPath = /bin/sh; 594 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; 595 | showEnvVarsInLog = 0; 596 | }; 597 | 54F3AE5618082AE400E1E688 /* ShellScript */ = { 598 | isa = PBXShellScriptBuildPhase; 599 | buildActionMask = 2147483647; 600 | files = ( 601 | ); 602 | inputPaths = ( 603 | ); 604 | outputPaths = ( 605 | ); 606 | runOnlyForDeploymentPostprocessing = 0; 607 | shellPath = /bin/sh; 608 | shellScript = "# Run the unit tests in this test bundle.\n\"${SYSTEM_DEVELOPER_DIR}/Tools/RunUnitTests\"\n"; 609 | }; 610 | 7854BEC60F31406CA9C284E7 /* Check Pods Manifest.lock */ = { 611 | isa = PBXShellScriptBuildPhase; 612 | buildActionMask = 2147483647; 613 | files = ( 614 | ); 615 | inputPaths = ( 616 | ); 617 | name = "Check Pods Manifest.lock"; 618 | outputPaths = ( 619 | ); 620 | runOnlyForDeploymentPostprocessing = 0; 621 | shellPath = /bin/sh; 622 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; 623 | showEnvVarsInLog = 0; 624 | }; 625 | 80B0D276277B4291ABDAD6CF /* Copy Pods Resources */ = { 626 | isa = PBXShellScriptBuildPhase; 627 | buildActionMask = 2147483647; 628 | files = ( 629 | ); 630 | inputPaths = ( 631 | ); 632 | name = "Copy Pods Resources"; 633 | outputPaths = ( 634 | ); 635 | runOnlyForDeploymentPostprocessing = 0; 636 | shellPath = /bin/sh; 637 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Specs-iOS/Pods-Specs-iOS-resources.sh\"\n"; 638 | showEnvVarsInLog = 0; 639 | }; 640 | 8F58412594AB4B62BD72EB53 /* Check Pods Manifest.lock */ = { 641 | isa = PBXShellScriptBuildPhase; 642 | buildActionMask = 2147483647; 643 | files = ( 644 | ); 645 | inputPaths = ( 646 | ); 647 | name = "Check Pods Manifest.lock"; 648 | outputPaths = ( 649 | ); 650 | runOnlyForDeploymentPostprocessing = 0; 651 | shellPath = /bin/sh; 652 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; 653 | showEnvVarsInLog = 0; 654 | }; 655 | 95F54BF0BB504B1783E7A15E /* Copy Pods Resources */ = { 656 | isa = PBXShellScriptBuildPhase; 657 | buildActionMask = 2147483647; 658 | files = ( 659 | ); 660 | inputPaths = ( 661 | ); 662 | name = "Copy Pods Resources"; 663 | outputPaths = ( 664 | ); 665 | runOnlyForDeploymentPostprocessing = 0; 666 | shellPath = /bin/sh; 667 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Specs-Mac/Pods-Specs-Mac-resources.sh\"\n"; 668 | showEnvVarsInLog = 0; 669 | }; 670 | A5CEBE251F3B4BF0A09218AC /* Copy Pods Resources */ = { 671 | isa = PBXShellScriptBuildPhase; 672 | buildActionMask = 2147483647; 673 | files = ( 674 | ); 675 | inputPaths = ( 676 | ); 677 | name = "Copy Pods Resources"; 678 | outputPaths = ( 679 | ); 680 | runOnlyForDeploymentPostprocessing = 0; 681 | shellPath = /bin/sh; 682 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-RBBAnimationTest/Pods-RBBAnimationTest-resources.sh\"\n"; 683 | showEnvVarsInLog = 0; 684 | }; 685 | /* End PBXShellScriptBuildPhase section */ 686 | 687 | /* Begin PBXSourcesBuildPhase section */ 688 | 5466C564180849D100652BDC /* Sources */ = { 689 | isa = PBXSourcesBuildPhase; 690 | buildActionMask = 2147483647; 691 | files = ( 692 | 545D5AB7180AFCA500FC94AB /* RBBAnimationListViewController.m in Sources */, 693 | 545D5AB6180AFCA500FC94AB /* CAAnimation+Name.m in Sources */, 694 | 5466C59818084BA200652BDC /* RBBAnimationViewController.m in Sources */, 695 | 5466C574180849D200652BDC /* main.m in Sources */, 696 | 5466C578180849D200652BDC /* RBBAppDelegate.m in Sources */, 697 | ); 698 | runOnlyForDeploymentPostprocessing = 0; 699 | }; 700 | 549ECA8F18F814A000D968C7 /* Sources */ = { 701 | isa = PBXSourcesBuildPhase; 702 | buildActionMask = 2147483647; 703 | files = ( 704 | 549ECAC518F8157200D968C7 /* RBBSpringAnimation.m in Sources */, 705 | 549ECAC918F8157200D968C7 /* RBBEasingFunction.m in Sources */, 706 | 549ECAC118F8157200D968C7 /* RBBCustomAnimation.m in Sources */, 707 | 540F65B018F83EB3005A6BB8 /* NSColor+PlatformIndependence.m in Sources */, 708 | 549ECAC318F8157200D968C7 /* RBBTweenAnimation.m in Sources */, 709 | 549ECAC718F8157200D968C7 /* RBBLinearInterpolation.m in Sources */, 710 | 549ECABF18F8157200D968C7 /* RBBAnimation.m in Sources */, 711 | 549ECACD18F8157200D968C7 /* RBBBlockBasedArray.m in Sources */, 712 | 549ECACB18F8157200D968C7 /* RBBCubicBezier.m in Sources */, 713 | 540F65A918F82347005A6BB8 /* NSValue+PlatformIndependence.m in Sources */, 714 | ); 715 | runOnlyForDeploymentPostprocessing = 0; 716 | }; 717 | 549ECAA518F814A000D968C7 /* Sources */ = { 718 | isa = PBXSourcesBuildPhase; 719 | buildActionMask = 2147483647; 720 | files = ( 721 | 549ECABD18F8155800D968C7 /* RBBBlockBasedArraySpec.m in Sources */, 722 | 549ECABE18F8155B00D968C7 /* RBBSpringAnimationSpec.m in Sources */, 723 | 540F65AC18F82C67005A6BB8 /* RBBLinearInterpolationSpec.m in Sources */, 724 | ); 725 | runOnlyForDeploymentPostprocessing = 0; 726 | }; 727 | 54F3AE261807394800E1E688 /* Sources */ = { 728 | isa = PBXSourcesBuildPhase; 729 | buildActionMask = 2147483647; 730 | files = ( 731 | 5479BEA4181D8008009811FD /* RBBCustomAnimation.m in Sources */, 732 | 545D5ABF180B2D3F00FC94AB /* RBBCubicBezier.m in Sources */, 733 | 540F65B318F83F98005A6BB8 /* UIColor+PlatformIndependence.m in Sources */, 734 | 54D5EA89181AE8620014896C /* RBBLinearInterpolation.m in Sources */, 735 | 545D5AC2180B5E8400FC94AB /* RBBEasingFunction.m in Sources */, 736 | 5466C56118082BEB00652BDC /* RBBBlockBasedArray.m in Sources */, 737 | 545D5ABA180B1FAE00FC94AB /* RBBTweenAnimation.m in Sources */, 738 | 545D5AC5180C138D00FC94AB /* RBBSpringAnimation.m in Sources */, 739 | 54F3AE351807394800E1E688 /* RBBAnimation.m in Sources */, 740 | 540F65A818F82347005A6BB8 /* NSValue+PlatformIndependence.m in Sources */, 741 | ); 742 | runOnlyForDeploymentPostprocessing = 0; 743 | }; 744 | 54F3AE361807394800E1E688 /* Sources */ = { 745 | isa = PBXSourcesBuildPhase; 746 | buildActionMask = 2147483647; 747 | files = ( 748 | 5466C56318082D4200652BDC /* RBBBlockBasedArraySpec.m in Sources */, 749 | 549ECA8418F6ECFC00D968C7 /* RBBSpringAnimationSpec.m in Sources */, 750 | 540F65AB18F82B3E005A6BB8 /* RBBLinearInterpolationSpec.m in Sources */, 751 | ); 752 | runOnlyForDeploymentPostprocessing = 0; 753 | }; 754 | /* End PBXSourcesBuildPhase section */ 755 | 756 | /* Begin PBXTargetDependency section */ 757 | 5466C59418084B6400652BDC /* PBXTargetDependency */ = { 758 | isa = PBXTargetDependency; 759 | target = 54F3AE291807394800E1E688 /* RBBAnimation iOS */; 760 | targetProxy = 5466C59318084B6400652BDC /* PBXContainerItemProxy */; 761 | }; 762 | 549ECAAD18F814A000D968C7 /* PBXTargetDependency */ = { 763 | isa = PBXTargetDependency; 764 | target = 549ECA9318F814A000D968C7 /* RBBAnimation Mac */; 765 | targetProxy = 549ECAAC18F814A000D968C7 /* PBXContainerItemProxy */; 766 | }; 767 | 54F3AE411807394800E1E688 /* PBXTargetDependency */ = { 768 | isa = PBXTargetDependency; 769 | target = 54F3AE291807394800E1E688 /* RBBAnimation iOS */; 770 | targetProxy = 54F3AE401807394800E1E688 /* PBXContainerItemProxy */; 771 | }; 772 | /* End PBXTargetDependency section */ 773 | 774 | /* Begin PBXVariantGroup section */ 775 | 5466C570180849D200652BDC /* InfoPlist.strings */ = { 776 | isa = PBXVariantGroup; 777 | children = ( 778 | 5466C571180849D200652BDC /* en */, 779 | ); 780 | name = InfoPlist.strings; 781 | sourceTree = ""; 782 | }; 783 | /* End PBXVariantGroup section */ 784 | 785 | /* Begin XCBuildConfiguration section */ 786 | 5466C58E180849D200652BDC /* Debug */ = { 787 | isa = XCBuildConfiguration; 788 | baseConfigurationReference = ED73BC249900E38EB30B303F /* Pods-RBBAnimationTest.debug.xcconfig */; 789 | buildSettings = { 790 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 791 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 792 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 793 | FRAMEWORK_SEARCH_PATHS = ( 794 | "$(inherited)", 795 | "$(DEVELOPER_FRAMEWORKS_DIR)", 796 | ); 797 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 798 | GCC_PREFIX_HEADER = "RBBAnimationTest/RBBAnimationTest-Prefix.pch"; 799 | GCC_PREPROCESSOR_DEFINITIONS = ( 800 | "DEBUG=1", 801 | "$(inherited)", 802 | ); 803 | INFOPLIST_FILE = "RBBAnimationTest/RBBAnimationTest-Info.plist"; 804 | PRODUCT_NAME = "$(TARGET_NAME)"; 805 | WRAPPER_EXTENSION = app; 806 | }; 807 | name = Debug; 808 | }; 809 | 5466C58F180849D200652BDC /* Release */ = { 810 | isa = XCBuildConfiguration; 811 | baseConfigurationReference = 288615584456976E0663A0C5 /* Pods-RBBAnimationTest.release.xcconfig */; 812 | buildSettings = { 813 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 814 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 815 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 816 | FRAMEWORK_SEARCH_PATHS = ( 817 | "$(inherited)", 818 | "$(DEVELOPER_FRAMEWORKS_DIR)", 819 | ); 820 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 821 | GCC_PREFIX_HEADER = "RBBAnimationTest/RBBAnimationTest-Prefix.pch"; 822 | INFOPLIST_FILE = "RBBAnimationTest/RBBAnimationTest-Info.plist"; 823 | PRODUCT_NAME = "$(TARGET_NAME)"; 824 | WRAPPER_EXTENSION = app; 825 | }; 826 | name = Release; 827 | }; 828 | 549ECAB818F814A000D968C7 /* Debug */ = { 829 | isa = XCBuildConfiguration; 830 | buildSettings = { 831 | COMBINE_HIDPI_IMAGES = YES; 832 | DYLIB_COMPATIBILITY_VERSION = 1; 833 | DYLIB_CURRENT_VERSION = 1; 834 | FRAMEWORK_SEARCH_PATHS = ( 835 | "$(inherited)", 836 | "$(DEVELOPER_FRAMEWORKS_DIR)", 837 | ); 838 | FRAMEWORK_VERSION = A; 839 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 840 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 841 | GCC_PREFIX_HEADER = "RBBAnimation/RBBAnimation-Prefix.pch"; 842 | GCC_PREPROCESSOR_DEFINITIONS = ( 843 | "DEBUG=1", 844 | "$(inherited)", 845 | ); 846 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 847 | INFOPLIST_FILE = "RBBAnimation/RBBAnimation-Info.plist"; 848 | MACOSX_DEPLOYMENT_TARGET = 10.8; 849 | PRODUCT_NAME = "$(TARGET_NAME)"; 850 | SDKROOT = macosx; 851 | WRAPPER_EXTENSION = framework; 852 | }; 853 | name = Debug; 854 | }; 855 | 549ECAB918F814A000D968C7 /* Release */ = { 856 | isa = XCBuildConfiguration; 857 | buildSettings = { 858 | COMBINE_HIDPI_IMAGES = YES; 859 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 860 | DYLIB_COMPATIBILITY_VERSION = 1; 861 | DYLIB_CURRENT_VERSION = 1; 862 | FRAMEWORK_SEARCH_PATHS = ( 863 | "$(inherited)", 864 | "$(DEVELOPER_FRAMEWORKS_DIR)", 865 | ); 866 | FRAMEWORK_VERSION = A; 867 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 868 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 869 | GCC_PREFIX_HEADER = "RBBAnimation/RBBAnimation-Prefix.pch"; 870 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 871 | INFOPLIST_FILE = "RBBAnimation/RBBAnimation-Info.plist"; 872 | MACOSX_DEPLOYMENT_TARGET = 10.8; 873 | PRODUCT_NAME = "$(TARGET_NAME)"; 874 | SDKROOT = macosx; 875 | WRAPPER_EXTENSION = framework; 876 | }; 877 | name = Release; 878 | }; 879 | 549ECABB18F814A000D968C7 /* Debug */ = { 880 | isa = XCBuildConfiguration; 881 | baseConfigurationReference = 3E441AF5FD5F61A5ACBC325F /* Pods-Specs-Mac.debug.xcconfig */; 882 | buildSettings = { 883 | COMBINE_HIDPI_IMAGES = YES; 884 | FRAMEWORK_SEARCH_PATHS = ( 885 | "$(DEVELOPER_FRAMEWORKS_DIR)", 886 | "$(inherited)", 887 | ); 888 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 889 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 890 | GCC_PREFIX_HEADER = "Specs/Specs-Prefix.pch"; 891 | GCC_PREPROCESSOR_DEFINITIONS = ( 892 | "DEBUG=1", 893 | "$(inherited)", 894 | ); 895 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 896 | MACOSX_DEPLOYMENT_TARGET = 10.9; 897 | PRODUCT_NAME = "$(TARGET_NAME)"; 898 | SDKROOT = macosx; 899 | }; 900 | name = Debug; 901 | }; 902 | 549ECABC18F814A000D968C7 /* Release */ = { 903 | isa = XCBuildConfiguration; 904 | baseConfigurationReference = D2A7704395D460556362784E /* Pods-Specs-Mac.release.xcconfig */; 905 | buildSettings = { 906 | COMBINE_HIDPI_IMAGES = YES; 907 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 908 | FRAMEWORK_SEARCH_PATHS = ( 909 | "$(DEVELOPER_FRAMEWORKS_DIR)", 910 | "$(inherited)", 911 | ); 912 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 913 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 914 | GCC_PREFIX_HEADER = "Specs/Specs-Prefix.pch"; 915 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 916 | MACOSX_DEPLOYMENT_TARGET = 10.9; 917 | PRODUCT_NAME = "$(TARGET_NAME)"; 918 | SDKROOT = macosx; 919 | }; 920 | name = Release; 921 | }; 922 | 54F3AE4B1807394800E1E688 /* Debug */ = { 923 | isa = XCBuildConfiguration; 924 | buildSettings = { 925 | ALWAYS_SEARCH_USER_PATHS = NO; 926 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 927 | CLANG_CXX_LIBRARY = "libc++"; 928 | CLANG_ENABLE_MODULES = YES; 929 | CLANG_ENABLE_OBJC_ARC = YES; 930 | CLANG_WARN_BOOL_CONVERSION = YES; 931 | CLANG_WARN_CONSTANT_CONVERSION = YES; 932 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 933 | CLANG_WARN_EMPTY_BODY = YES; 934 | CLANG_WARN_ENUM_CONVERSION = YES; 935 | CLANG_WARN_INT_CONVERSION = YES; 936 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 937 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 938 | COPY_PHASE_STRIP = NO; 939 | GCC_C_LANGUAGE_STANDARD = gnu99; 940 | GCC_DYNAMIC_NO_PIC = NO; 941 | GCC_OPTIMIZATION_LEVEL = 0; 942 | GCC_PREPROCESSOR_DEFINITIONS = ( 943 | "DEBUG=1", 944 | "$(inherited)", 945 | ); 946 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 947 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 948 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 949 | GCC_WARN_UNDECLARED_SELECTOR = YES; 950 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 951 | GCC_WARN_UNUSED_FUNCTION = YES; 952 | GCC_WARN_UNUSED_VARIABLE = YES; 953 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 954 | ONLY_ACTIVE_ARCH = YES; 955 | SDKROOT = iphoneos; 956 | }; 957 | name = Debug; 958 | }; 959 | 54F3AE4C1807394800E1E688 /* Release */ = { 960 | isa = XCBuildConfiguration; 961 | buildSettings = { 962 | ALWAYS_SEARCH_USER_PATHS = NO; 963 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 964 | CLANG_CXX_LIBRARY = "libc++"; 965 | CLANG_ENABLE_MODULES = YES; 966 | CLANG_ENABLE_OBJC_ARC = YES; 967 | CLANG_WARN_BOOL_CONVERSION = YES; 968 | CLANG_WARN_CONSTANT_CONVERSION = YES; 969 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 970 | CLANG_WARN_EMPTY_BODY = YES; 971 | CLANG_WARN_ENUM_CONVERSION = YES; 972 | CLANG_WARN_INT_CONVERSION = YES; 973 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 974 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 975 | COPY_PHASE_STRIP = YES; 976 | ENABLE_NS_ASSERTIONS = NO; 977 | GCC_C_LANGUAGE_STANDARD = gnu99; 978 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 979 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 980 | GCC_WARN_UNDECLARED_SELECTOR = YES; 981 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 982 | GCC_WARN_UNUSED_FUNCTION = YES; 983 | GCC_WARN_UNUSED_VARIABLE = YES; 984 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 985 | SDKROOT = iphoneos; 986 | VALIDATE_PRODUCT = YES; 987 | }; 988 | name = Release; 989 | }; 990 | 54F3AE4E1807394800E1E688 /* Debug */ = { 991 | isa = XCBuildConfiguration; 992 | buildSettings = { 993 | DSTROOT = /tmp/RBBAnimation.dst; 994 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 995 | GCC_PREFIX_HEADER = "RBBAnimation/RBBAnimation-Prefix.pch"; 996 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 997 | OTHER_LDFLAGS = "-ObjC"; 998 | PRODUCT_NAME = "$(TARGET_NAME)"; 999 | SKIP_INSTALL = YES; 1000 | }; 1001 | name = Debug; 1002 | }; 1003 | 54F3AE4F1807394800E1E688 /* Release */ = { 1004 | isa = XCBuildConfiguration; 1005 | buildSettings = { 1006 | DSTROOT = /tmp/RBBAnimation.dst; 1007 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 1008 | GCC_PREFIX_HEADER = "RBBAnimation/RBBAnimation-Prefix.pch"; 1009 | IPHONEOS_DEPLOYMENT_TARGET = 7.0; 1010 | OTHER_LDFLAGS = "-ObjC"; 1011 | PRODUCT_NAME = "$(TARGET_NAME)"; 1012 | SKIP_INSTALL = YES; 1013 | }; 1014 | name = Release; 1015 | }; 1016 | 54F3AE511807394800E1E688 /* Debug */ = { 1017 | isa = XCBuildConfiguration; 1018 | baseConfigurationReference = 74ABD43AFADA521EF3D0EC21 /* Pods-Specs-iOS.debug.xcconfig */; 1019 | buildSettings = { 1020 | FRAMEWORK_SEARCH_PATHS = ( 1021 | "$(SDKROOT)/Developer/Library/Frameworks", 1022 | "$(inherited)", 1023 | "$(DEVELOPER_FRAMEWORKS_DIR)", 1024 | ); 1025 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 1026 | GCC_PREFIX_HEADER = "Specs/Specs-Prefix.pch"; 1027 | GCC_PREPROCESSOR_DEFINITIONS = ( 1028 | "DEBUG=1", 1029 | "$(inherited)", 1030 | ); 1031 | PRODUCT_NAME = "$(TARGET_NAME)"; 1032 | }; 1033 | name = Debug; 1034 | }; 1035 | 54F3AE521807394800E1E688 /* Release */ = { 1036 | isa = XCBuildConfiguration; 1037 | baseConfigurationReference = 7582873345F4B52FF68854CB /* Pods-Specs-iOS.release.xcconfig */; 1038 | buildSettings = { 1039 | FRAMEWORK_SEARCH_PATHS = ( 1040 | "$(SDKROOT)/Developer/Library/Frameworks", 1041 | "$(inherited)", 1042 | "$(DEVELOPER_FRAMEWORKS_DIR)", 1043 | ); 1044 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 1045 | GCC_PREFIX_HEADER = "Specs/Specs-Prefix.pch"; 1046 | PRODUCT_NAME = "$(TARGET_NAME)"; 1047 | }; 1048 | name = Release; 1049 | }; 1050 | /* End XCBuildConfiguration section */ 1051 | 1052 | /* Begin XCConfigurationList section */ 1053 | 5466C58D180849D200652BDC /* Build configuration list for PBXNativeTarget "RBBAnimationTest" */ = { 1054 | isa = XCConfigurationList; 1055 | buildConfigurations = ( 1056 | 5466C58E180849D200652BDC /* Debug */, 1057 | 5466C58F180849D200652BDC /* Release */, 1058 | ); 1059 | defaultConfigurationIsVisible = 0; 1060 | defaultConfigurationName = Release; 1061 | }; 1062 | 549ECAB718F814A000D968C7 /* Build configuration list for PBXNativeTarget "RBBAnimation Mac" */ = { 1063 | isa = XCConfigurationList; 1064 | buildConfigurations = ( 1065 | 549ECAB818F814A000D968C7 /* Debug */, 1066 | 549ECAB918F814A000D968C7 /* Release */, 1067 | ); 1068 | defaultConfigurationIsVisible = 0; 1069 | defaultConfigurationName = Release; 1070 | }; 1071 | 549ECABA18F814A000D968C7 /* Build configuration list for PBXNativeTarget "Specs-Mac" */ = { 1072 | isa = XCConfigurationList; 1073 | buildConfigurations = ( 1074 | 549ECABB18F814A000D968C7 /* Debug */, 1075 | 549ECABC18F814A000D968C7 /* Release */, 1076 | ); 1077 | defaultConfigurationIsVisible = 0; 1078 | defaultConfigurationName = Release; 1079 | }; 1080 | 54F3AE251807394800E1E688 /* Build configuration list for PBXProject "RBBAnimation" */ = { 1081 | isa = XCConfigurationList; 1082 | buildConfigurations = ( 1083 | 54F3AE4B1807394800E1E688 /* Debug */, 1084 | 54F3AE4C1807394800E1E688 /* Release */, 1085 | ); 1086 | defaultConfigurationIsVisible = 0; 1087 | defaultConfigurationName = Release; 1088 | }; 1089 | 54F3AE4D1807394800E1E688 /* Build configuration list for PBXNativeTarget "RBBAnimation iOS" */ = { 1090 | isa = XCConfigurationList; 1091 | buildConfigurations = ( 1092 | 54F3AE4E1807394800E1E688 /* Debug */, 1093 | 54F3AE4F1807394800E1E688 /* Release */, 1094 | ); 1095 | defaultConfigurationIsVisible = 0; 1096 | defaultConfigurationName = Release; 1097 | }; 1098 | 54F3AE501807394800E1E688 /* Build configuration list for PBXNativeTarget "Specs-iOS" */ = { 1099 | isa = XCConfigurationList; 1100 | buildConfigurations = ( 1101 | 54F3AE511807394800E1E688 /* Debug */, 1102 | 54F3AE521807394800E1E688 /* Release */, 1103 | ); 1104 | defaultConfigurationIsVisible = 0; 1105 | defaultConfigurationName = Release; 1106 | }; 1107 | /* End XCConfigurationList section */ 1108 | }; 1109 | rootObject = 54F3AE221807394800E1E688 /* Project object */; 1110 | } 1111 | -------------------------------------------------------------------------------- /RBBAnimation.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /RBBAnimation.xcodeproj/xcshareddata/xcschemes/RBBAnimation Mac.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 52 | 53 | 54 | 55 | 61 | 62 | 64 | 65 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /RBBAnimation.xcodeproj/xcshareddata/xcschemes/RBBAnimation iOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 52 | 53 | 54 | 55 | 61 | 62 | 64 | 65 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /RBBAnimation.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /RBBAnimation/NSColor+PlatformIndependence.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSColor+PlatformIndependence.h 3 | // RBBAnimation 4 | // 5 | // Created by Robert Böhnke on 11/04/14. 6 | // Copyright (c) 2014 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSColor (PlatformIndependence) 12 | 13 | + (instancetype)rbb_colorWithHue:(CGFloat)hue saturation:(CGFloat)saturation brightness:(CGFloat)brightness alpha:(CGFloat)alpha; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /RBBAnimation/NSColor+PlatformIndependence.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSColor+PlatformIndependence.m 3 | // RBBAnimation 4 | // 5 | // Created by Robert Böhnke on 11/04/14. 6 | // Copyright (c) 2014 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #import "NSColor+PlatformIndependence.h" 10 | 11 | @implementation NSColor (PlatformIndependence) 12 | 13 | + (instancetype)rbb_colorWithHue:(CGFloat)hue saturation:(CGFloat)saturation brightness:(CGFloat)brightness alpha:(CGFloat)alpha { 14 | return [self colorWithDeviceHue:hue saturation:saturation brightness:brightness alpha:alpha];; 15 | } 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /RBBAnimation/NSValue+PlatformIndependence.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSValue+PlatformIndependence.h 3 | // RBBAnimation 4 | // 5 | // Created by Robert Böhnke on 11/04/14. 6 | // Copyright (c) 2014 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSValue (PlatformIndependence) 12 | 13 | + (instancetype)rbb_valueWithCGRect:(CGRect)rect; 14 | + (instancetype)rbb_valueWithCGSize:(CGSize)size; 15 | + (instancetype)rbb_valueWithCGPoint:(CGPoint)point; 16 | 17 | - (CGRect)rbb_CGRectValue; 18 | - (CGSize)rbb_CGSizeValue; 19 | - (CGPoint)rbb_CGPointValue; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /RBBAnimation/NSValue+PlatformIndependence.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSValue+PlatformIndependence.m 3 | // RBBAnimation 4 | // 5 | // Created by Robert Böhnke on 11/04/14. 6 | // Copyright (c) 2014 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR 10 | #import 11 | #endif 12 | 13 | #import "NSValue+PlatformIndependence.h" 14 | 15 | @implementation NSValue (PlatformIndependence) 16 | 17 | #if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR 18 | + (instancetype)rbb_valueWithCGRect:(CGRect)rect { 19 | return [self valueWithCGRect:rect]; 20 | } 21 | 22 | + (instancetype)rbb_valueWithCGSize:(CGSize)size { 23 | return [self valueWithCGSize:size]; 24 | } 25 | 26 | + (instancetype)rbb_valueWithCGPoint:(CGPoint)point { 27 | return [self valueWithCGPoint:point]; 28 | } 29 | 30 | - (CGRect)rbb_CGRectValue { 31 | return [self CGRectValue]; 32 | } 33 | 34 | - (CGSize)rbb_CGSizeValue { 35 | return [self CGSizeValue]; 36 | } 37 | 38 | - (CGPoint)rbb_CGPointValue { 39 | return [self CGPointValue]; 40 | } 41 | #elif TARGET_OS_MAC 42 | + (instancetype)rbb_valueWithCGRect:(CGRect)rect { 43 | return [self valueWithRect:rect]; 44 | } 45 | 46 | + (instancetype)rbb_valueWithCGSize:(CGSize)size { 47 | return [self valueWithSize:size]; 48 | } 49 | 50 | + (instancetype)rbb_valueWithCGPoint:(CGPoint)point { 51 | return [self valueWithPoint:point]; 52 | } 53 | 54 | - (CGRect)rbb_CGRectValue { 55 | return [self rectValue]; 56 | } 57 | 58 | - (CGSize)rbb_CGSizeValue { 59 | return [self sizeValue]; 60 | } 61 | 62 | - (CGPoint)rbb_CGPointValue { 63 | return [self pointValue]; 64 | } 65 | #endif 66 | 67 | @end 68 | -------------------------------------------------------------------------------- /RBBAnimation/RBBAnimation-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleExecutable 6 | ${EXECUTABLE_NAME} 7 | CFBundleIdentifier 8 | com.robertboehnke.${PRODUCT_NAME:rfc1034identifier} 9 | CFBundleInfoDictionaryVersion 10 | 6.0 11 | CFBundleName 12 | ${PRODUCT_NAME} 13 | CFBundlePackageType 14 | FMWK 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | NSHumanReadableCopyright 22 | Copyright © 2014 Robert Böhnke. All rights reserved. 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /RBBAnimation/RBBAnimation-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #ifdef __OBJC__ 8 | #import 9 | #endif 10 | -------------------------------------------------------------------------------- /RBBAnimation/RBBAnimation.h: -------------------------------------------------------------------------------- 1 | // 2 | // RBBAnimation.h 3 | // RBBAnimation 4 | // 5 | // Created by Robert Böhnke on 10/10/13. 6 | // Copyright (c) 2013 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef id (^RBBAnimationBlock)(CGFloat t, CGFloat duration); 12 | 13 | @interface RBBAnimation : CAKeyframeAnimation 14 | 15 | @property (readonly, nonatomic, copy) RBBAnimationBlock animationBlock; 16 | 17 | @end 18 | 19 | @interface RBBAnimation (Unavailable) 20 | 21 | - (void)setValues:(NSArray *)values __attribute__((unavailable("values cannot be set on RBBAnimation"))); 22 | 23 | @property (readwrite, atomic, assign) CGPathRef path __attribute__((unavailable("path is not available on RBBAnimation"))); 24 | 25 | @property (readwrite, atomic, copy) NSString *rotationMode __attribute__((unavailable("rotationMode is not available on RBBAnimation"))); 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /RBBAnimation/RBBAnimation.m: -------------------------------------------------------------------------------- 1 | // 2 | // RBBAnimation.m 3 | // RBBAnimation 4 | // 5 | // Created by Robert Böhnke on 10/10/13. 6 | // Copyright (c) 2013 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #import "RBBBlockBasedArray.h" 10 | #import "RBBLinearInterpolation.h" 11 | 12 | #import "RBBAnimation.h" 13 | 14 | @interface RBBAnimation () 15 | 16 | @end 17 | 18 | @implementation RBBAnimation 19 | 20 | #pragma mark - KVO 21 | 22 | + (NSSet *)keyPathsForValuesAffectingValues { 23 | return [NSSet setWithArray:@[ @"animationBlock", @"duration" ]]; 24 | } 25 | 26 | #pragma mark - CAKeyframeAnimation 27 | 28 | - (NSArray *)values { 29 | RBBAnimationBlock block = [self.animationBlock copy]; 30 | 31 | CGFloat duration = self.duration; 32 | 33 | return [RBBBlockBasedArray arrayWithCount:duration * 60 block:^id(NSUInteger idx) { 34 | return block(idx / 60.0, duration); 35 | }]; 36 | } 37 | 38 | #pragma mark - Unavailable 39 | 40 | - (void)setPath:(CGPathRef)path { 41 | return; 42 | } 43 | 44 | - (CGPathRef)path { 45 | return NULL; 46 | } 47 | 48 | - (void)setRotationMode:(NSString *)rotationMode { 49 | return; 50 | } 51 | 52 | - (NSString *)rotationMode { 53 | return nil; 54 | } 55 | 56 | - (void)setValues:(NSArray *)values { 57 | return; 58 | } 59 | 60 | @end 61 | -------------------------------------------------------------------------------- /RBBAnimation/RBBBlockBasedArray.h: -------------------------------------------------------------------------------- 1 | // 2 | // RBBBlockBasedArray.h 3 | // RBBAnimation 4 | // 5 | // Created by Robert Böhnke on 10/11/13. 6 | // Copyright (c) 2013 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef id (^RBBBlockBasedArrayBlock)(NSUInteger idx); 12 | 13 | @interface RBBBlockBasedArray : NSArray 14 | 15 | + (instancetype)arrayWithCount:(NSUInteger)count block:(RBBBlockBasedArrayBlock)block; 16 | 17 | - (instancetype)initWithCount:(NSUInteger)count block:(RBBBlockBasedArrayBlock)block; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /RBBAnimation/RBBBlockBasedArray.m: -------------------------------------------------------------------------------- 1 | // 2 | // RBBBlockBasedArray.m 3 | // RBBAnimation 4 | // 5 | // Created by Robert Böhnke on 10/11/13. 6 | // Copyright (c) 2013 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #import "RBBBlockBasedArray.h" 10 | 11 | @implementation RBBBlockBasedArray { 12 | NSUInteger _count; 13 | RBBBlockBasedArrayBlock _block; 14 | } 15 | 16 | #pragma mark - Lifecycle 17 | 18 | + (instancetype)arrayWithCount:(NSUInteger)count block:(RBBBlockBasedArrayBlock)block { 19 | return [[self alloc] initWithCount:count block:block]; 20 | } 21 | 22 | - (instancetype)initWithCount:(NSUInteger)count block:(RBBBlockBasedArrayBlock)block { 23 | self = [super init]; 24 | if (self == nil) return nil; 25 | 26 | _count = count; 27 | _block = [block copy]; 28 | 29 | return self; 30 | } 31 | 32 | - (instancetype)init { 33 | return [self initWithCount:0 block:nil]; 34 | } 35 | 36 | - (instancetype)initWithObjects:(const id [])objects count:(NSUInteger)cnt { 37 | NSArray *otherArray = [NSArray arrayWithObjects:objects count:cnt]; 38 | 39 | return [self initWithCount:cnt block:^(NSUInteger idx) { 40 | return otherArray[idx]; 41 | }]; 42 | } 43 | 44 | #pragma mark - NSArray primitive methods 45 | 46 | - (NSUInteger)count { 47 | return _count; 48 | } 49 | 50 | - (id)objectAtIndex:(NSUInteger)index { 51 | return _block(index); 52 | } 53 | 54 | #pragma mark - NSObject 55 | 56 | - (id)copyWithZone:(NSZone *)zone { 57 | return [[self.class allocWithZone:zone] initWithCount:_count block:_block]; 58 | } 59 | 60 | @end 61 | -------------------------------------------------------------------------------- /RBBAnimation/RBBCubicBezier.h: -------------------------------------------------------------------------------- 1 | // 2 | // RBBCubicBezier.h 3 | // RBBAnimation 4 | // 5 | // Created by Robert Böhnke on 10/13/13. 6 | // Copyright (c) 2013 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "RBBTweenAnimation.h" 12 | 13 | extern RBBEasingFunction RBBCubicBezier(CGFloat x1, CGFloat y1, CGFloat x2, CGFloat y2); -------------------------------------------------------------------------------- /RBBAnimation/RBBCubicBezier.m: -------------------------------------------------------------------------------- 1 | // 2 | // RBBCubicBezier.m 3 | // RBBAnimation 4 | // 5 | // Created by Robert Böhnke on 10/13/13. 6 | // Copyright (c) 2013 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #import "RBBCubicBezier.h" 10 | 11 | #define A(a1, a2) (1.0 - 3.0 * a2 + 3.0 * a1) 12 | #define B(a1, a2) (3.0 * a2 - 6.0 * a1) 13 | #define C(a1) (3.0 * a1) 14 | 15 | CGFloat RBBCubicBezierCalculate(CGFloat t, CGFloat a1, CGFloat a2) { 16 | return ((A(a1, a2) * t + B(a1, a2)) * t + C(a1)) * t; 17 | } 18 | 19 | CGFloat RBBCubicBezierSlope(CGFloat t, CGFloat a1, CGFloat a2) { 20 | return 3.0 * A(a1, a2) * t * t + 2.0 * B(a1, a2) * t + C(a1); 21 | } 22 | 23 | CGFloat RBBCubicBezierBinarySubdivide(CGFloat x, CGFloat x1, CGFloat x2) { 24 | CGFloat epsilon = 0.0000001; 25 | NSUInteger maxIterations = 10; 26 | 27 | CGFloat start = 0; 28 | CGFloat end = 1; 29 | 30 | CGFloat currentX; 31 | CGFloat currentT; 32 | 33 | NSUInteger i = 0; 34 | do { 35 | currentT = start + (end - start) / 2; 36 | currentX = RBBCubicBezierCalculate(currentT, x1, x2) - x; 37 | 38 | if (currentX > 0) { 39 | end = currentT; 40 | } else { 41 | start = currentT; 42 | } 43 | 44 | } while (fabs(currentX) > epsilon && ++i < maxIterations); 45 | 46 | return currentT; 47 | } 48 | 49 | extern RBBEasingFunction RBBCubicBezier(CGFloat x1, CGFloat y1, CGFloat x2, CGFloat y2) { 50 | if (x1 == y1 && x2 == y2) return RBBEasingFunctionLinear; 51 | 52 | return ^(CGFloat x) { 53 | CGFloat t = RBBCubicBezierBinarySubdivide(x, x1, x2); 54 | 55 | return RBBCubicBezierCalculate(t, y1, y2); 56 | }; 57 | } -------------------------------------------------------------------------------- /RBBAnimation/RBBCustomAnimation.h: -------------------------------------------------------------------------------- 1 | // 2 | // RBBCustomAnimation.h 3 | // RBBAnimation 4 | // 5 | // Created by Robert Böhnke on 10/27/13. 6 | // Copyright (c) 2013 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #import "RBBAnimation.h" 10 | 11 | @interface RBBCustomAnimation : RBBAnimation 12 | 13 | @property (readwrite, nonatomic, copy) RBBAnimationBlock animationBlock; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /RBBAnimation/RBBCustomAnimation.m: -------------------------------------------------------------------------------- 1 | // 2 | // RBBCustomAnimation.m 3 | // RBBAnimation 4 | // 5 | // Created by Robert Böhnke on 10/27/13. 6 | // Copyright (c) 2013 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #import "RBBCustomAnimation.h" 10 | 11 | @implementation RBBCustomAnimation 12 | 13 | @synthesize animationBlock = _animationBlock; 14 | 15 | #pragma mark - NSObject 16 | 17 | - (id)copyWithZone:(NSZone *)zone { 18 | RBBCustomAnimation *copy = [super copyWithZone:zone]; 19 | if (copy == nil) return nil; 20 | 21 | copy->_animationBlock = [_animationBlock copy]; 22 | 23 | return copy; 24 | } 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /RBBAnimation/RBBEasingFunction.h: -------------------------------------------------------------------------------- 1 | // 2 | // RBBEasingFunction.h 3 | // RBBAnimation 4 | // 5 | // Created by Robert Böhnke on 10/14/13. 6 | // Copyright (c) 2013 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef CGFloat (^RBBEasingFunction)(CGFloat t); 12 | 13 | extern RBBEasingFunction const RBBEasingFunctionLinear; 14 | 15 | extern RBBEasingFunction const RBBEasingFunctionEaseInQuad; 16 | extern RBBEasingFunction const RBBEasingFunctionEaseOutQuad; 17 | extern RBBEasingFunction const RBBEasingFunctionEaseInOutQuad; 18 | 19 | extern RBBEasingFunction const RBBEasingFunctionEaseInCubic; 20 | extern RBBEasingFunction const RBBEasingFunctionEaseOutCubic; 21 | extern RBBEasingFunction const RBBEasingFunctionEaseInOutCubic; 22 | 23 | extern RBBEasingFunction const RBBEasingFunctionEaseInQuart; 24 | extern RBBEasingFunction const RBBEasingFunctionEaseOutQuart; 25 | extern RBBEasingFunction const RBBEasingFunctionEaseInOutQuart; 26 | 27 | extern RBBEasingFunction const RBBEasingFunctionEaseInBounce; 28 | extern RBBEasingFunction const RBBEasingFunctionEaseOutBounce; 29 | 30 | extern RBBEasingFunction const RBBEasingFunctionEaseInExpo; 31 | extern RBBEasingFunction const RBBEasingFunctionEaseOutExpo; 32 | extern RBBEasingFunction const RBBEasingFunctionEaseInOutExpo; 33 | -------------------------------------------------------------------------------- /RBBAnimation/RBBEasingFunction.m: -------------------------------------------------------------------------------- 1 | // 2 | // RBBEasingFunction.m 3 | // RBBAnimation 4 | // 5 | // Created by Robert Böhnke on 10/14/13. 6 | // Copyright (c) 2013 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #import "RBBEasingFunction.h" 10 | 11 | #if CGFLOAT_IS_DOUBLE 12 | #define POW(X, Y) pow(X, Y) 13 | #else 14 | #define POW(X, Y) powf(X, Y) 15 | #endif 16 | 17 | RBBEasingFunction const RBBEasingFunctionLinear = ^CGFloat(CGFloat t) { 18 | return t; 19 | }; 20 | 21 | RBBEasingFunction const RBBEasingFunctionEaseInQuad = ^CGFloat(CGFloat t) { 22 | return t * t; 23 | }; 24 | 25 | RBBEasingFunction const RBBEasingFunctionEaseOutQuad = ^CGFloat(CGFloat t) { 26 | return t * (2 - t); 27 | }; 28 | 29 | RBBEasingFunction const RBBEasingFunctionEaseInOutQuad = ^CGFloat(CGFloat t) { 30 | if (t < 0.5) { 31 | return 2 * t * t; 32 | } else { 33 | return -1 + (4 - 2 * t) * t; 34 | } 35 | }; 36 | 37 | RBBEasingFunction const RBBEasingFunctionEaseInCubic = ^CGFloat(CGFloat t) { 38 | return t * t * t; 39 | }; 40 | 41 | RBBEasingFunction const RBBEasingFunctionEaseOutCubic = ^CGFloat(CGFloat t) { 42 | return POW(t - 1, 3) + 1; 43 | }; 44 | 45 | RBBEasingFunction const RBBEasingFunctionEaseInOutCubic = ^CGFloat(CGFloat t) { 46 | if (t < 0.5) { 47 | return 4 * POW(t, 3); 48 | } else { 49 | return (t - 1) * POW(2 * t - 2, 2) + 1; 50 | } 51 | }; 52 | 53 | RBBEasingFunction const RBBEasingFunctionEaseInQuart = ^(CGFloat t) { 54 | return t * t * t * t; 55 | }; 56 | 57 | RBBEasingFunction const RBBEasingFunctionEaseOutQuart = ^(CGFloat t) { 58 | return 1 - POW(t - 1, 4); 59 | }; 60 | 61 | RBBEasingFunction const RBBEasingFunctionEaseInOutQuart = ^(CGFloat t) { 62 | if (t < 0.5) { 63 | return 8 * POW(t, 4); 64 | } else { 65 | return -1 / 2 * POW(2 * t - 2, 4) + 1; 66 | } 67 | }; 68 | 69 | RBBEasingFunction const RBBEasingFunctionEaseInBounce = ^CGFloat(CGFloat t) { 70 | return 1.0 - RBBEasingFunctionEaseOutBounce(1.0 - t); 71 | }; 72 | 73 | RBBEasingFunction const RBBEasingFunctionEaseOutBounce = ^CGFloat(CGFloat t) { 74 | if (t < 4.0 / 11.0) { 75 | return POW(11.0 / 4.0, 2) * POW(t, 2); 76 | } 77 | 78 | if (t < 8.0 / 11.0) { 79 | return 3.0 / 4.0 + POW(11.0 / 4.0, 2) * POW(t - 6.0 / 11.0, 2); 80 | } 81 | 82 | if (t < 10.0 / 11.0) { 83 | return 15.0 /16.0 + POW(11.0 / 4.0, 2) * POW(t - 9.0 / 11.0, 2); 84 | } 85 | 86 | return 63.0 / 64.0 + POW(11.0 / 4.0, 2) * POW(t - 21.0 / 22.0, 2); 87 | }; 88 | 89 | RBBEasingFunction const RBBEasingFunctionEaseInExpo = ^CGFloat(CGFloat t) { 90 | return t == 0 ? 0.0 : POW(2, 10 * (t - 1)); 91 | }; 92 | 93 | RBBEasingFunction const RBBEasingFunctionEaseOutExpo = ^CGFloat(CGFloat t) { 94 | return t == 1.0 ? 1 : 1 - POW(2, - 10 * t); 95 | }; 96 | 97 | RBBEasingFunction const RBBEasingFunctionEaseInOutExpo = ^CGFloat(CGFloat t) { 98 | if (t == 0) return 0.0; 99 | if (t == 1) return 1.0; 100 | 101 | if (t < 0.5) { 102 | return POW(2, 10 * (2 * t - 1)) / 2; 103 | } else { 104 | return 1 - POW(2, -10 * (2 * t - 1)) / 2; 105 | } 106 | }; 107 | -------------------------------------------------------------------------------- /RBBAnimation/RBBLinearInterpolation.h: -------------------------------------------------------------------------------- 1 | // 2 | // RBBLinearInterpolation.h 3 | // RBBAnimation 4 | // 5 | // Created by Robert Böhnke on 10/25/13. 6 | // Copyright (c) 2013 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef id (^RBBLinearInterpolation)(CGFloat fraction); 12 | 13 | extern RBBLinearInterpolation RBBInterpolate(id from, id to); 14 | -------------------------------------------------------------------------------- /RBBAnimation/RBBLinearInterpolation.m: -------------------------------------------------------------------------------- 1 | // 2 | // RBBLinearInterpolation.m 3 | // RBBAnimation 4 | // 5 | // Created by Robert Böhnke on 10/25/13. 6 | // Copyright (c) 2013 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR 10 | #import 11 | 12 | #import "UIColor+PlatformIndependence.h" 13 | 14 | #define RBBColor UIColor 15 | #else 16 | #import 17 | 18 | #import "NSColor+PlatformIndependence.h" 19 | 20 | #define RBBColor NSColor 21 | #endif 22 | 23 | #import "NSValue+PlatformIndependence.h" 24 | 25 | #import "RBBLinearInterpolation.h" 26 | 27 | static RBBLinearInterpolation RBBInterpolateCATransform3D(CATransform3D from, CATransform3D to) { 28 | CATransform3D delta = { 29 | .m11 = to.m11 - from.m11, 30 | .m12 = to.m12 - from.m12, 31 | .m13 = to.m13 - from.m13, 32 | .m14 = to.m14 - from.m14, 33 | .m21 = to.m21 - from.m21, 34 | .m22 = to.m22 - from.m22, 35 | .m23 = to.m23 - from.m23, 36 | .m24 = to.m24 - from.m24, 37 | .m31 = to.m31 - from.m31, 38 | .m32 = to.m32 - from.m32, 39 | .m33 = to.m33 - from.m33, 40 | .m34 = to.m34 - from.m34, 41 | .m41 = to.m41 - from.m41, 42 | .m42 = to.m42 - from.m42, 43 | .m43 = to.m43 - from.m43, 44 | .m44 = to.m44 - from.m44 45 | }; 46 | 47 | return ^(CGFloat fraction) { 48 | CATransform3D transform = { 49 | .m11 = from.m11 + fraction * delta.m11, 50 | .m12 = from.m12 + fraction * delta.m12, 51 | .m13 = from.m13 + fraction * delta.m13, 52 | .m14 = from.m14 + fraction * delta.m14, 53 | .m21 = from.m21 + fraction * delta.m21, 54 | .m22 = from.m22 + fraction * delta.m22, 55 | .m23 = from.m23 + fraction * delta.m23, 56 | .m24 = from.m24 + fraction * delta.m24, 57 | .m31 = from.m31 + fraction * delta.m31, 58 | .m32 = from.m32 + fraction * delta.m32, 59 | .m33 = from.m33 + fraction * delta.m33, 60 | .m34 = from.m34 + fraction * delta.m34, 61 | .m41 = from.m41 + fraction * delta.m41, 62 | .m42 = from.m42 + fraction * delta.m42, 63 | .m43 = from.m43 + fraction * delta.m43, 64 | .m44 = from.m44 + fraction * delta.m44 65 | }; 66 | 67 | return [NSValue valueWithCATransform3D:transform]; 68 | }; 69 | } 70 | 71 | static RBBLinearInterpolation RBBInterpolateCGRect(CGRect from, CGRect to) { 72 | CGFloat deltaX = to.origin.x - from.origin.x; 73 | CGFloat deltaY = to.origin.y - from.origin.y; 74 | CGFloat deltaWidth = to.size.width - from.size.width; 75 | CGFloat deltaHeight = to.size.height - from.size.height; 76 | 77 | return ^(CGFloat fraction) { 78 | CGRect rect = { 79 | .origin.x = from.origin.x + fraction * deltaX, 80 | .origin.y = from.origin.y + fraction * deltaY, 81 | .size.width = from.size.width + fraction * deltaWidth, 82 | .size.height = from.size.height + fraction * deltaHeight 83 | }; 84 | 85 | return [NSValue rbb_valueWithCGRect:rect]; 86 | }; 87 | } 88 | 89 | static RBBLinearInterpolation RBBInterpolateCGPoint(CGPoint from, CGPoint to) { 90 | CGFloat deltaX = to.x - from.x; 91 | CGFloat deltaY = to.y - from.y; 92 | 93 | return ^(CGFloat fraction) { 94 | CGPoint point = { 95 | .x = from.x + fraction * deltaX, 96 | .y = from.y + fraction * deltaY, 97 | }; 98 | 99 | return [NSValue rbb_valueWithCGPoint:point]; 100 | }; 101 | } 102 | 103 | static RBBLinearInterpolation RBBInterpolateCGSize(CGSize from, CGSize to) { 104 | CGFloat deltaWidth = to.width - from.width; 105 | CGFloat deltaHeight = to.height - from.height; 106 | 107 | return ^(CGFloat fraction) { 108 | CGSize size = { 109 | .width = from.width + fraction * deltaWidth, 110 | .height = from.height + fraction * deltaHeight, 111 | }; 112 | 113 | return [NSValue rbb_valueWithCGSize:size]; 114 | }; 115 | } 116 | 117 | static RBBLinearInterpolation RBBInterpolateCGFloat(CGFloat from, CGFloat to) { 118 | CGFloat delta = to - from; 119 | 120 | return ^(CGFloat fraction) { 121 | return @(from + fraction * delta); 122 | }; 123 | }; 124 | 125 | // TODO: Color spaces can present a problem. 126 | // 127 | // For example, if [UIColor/NSColor whiteColor] is used, the color space is 128 | // white, and this fails. 129 | // 130 | // A comprehensive conversion process should always bring the colors into an 131 | // HSBA-compatible color space. In the mean time, always create colors using 132 | // +olorWithHue:saturation:brightness:alpha: method. 133 | static RBBLinearInterpolation RBBInterpolateColor(RBBColor *from, RBBColor *to) { 134 | CGFloat fromHue = 0.0f; 135 | CGFloat fromSaturation = 0.0f; 136 | CGFloat fromBrightness = 0.0f; 137 | CGFloat fromAlpha = 0.0f; 138 | 139 | [from getHue:&fromHue saturation:&fromSaturation brightness:&fromBrightness alpha:&fromAlpha]; 140 | 141 | CGFloat toHue = 0.0f; 142 | CGFloat toSaturation = 0.0f; 143 | CGFloat toBrightness = 0.0f; 144 | CGFloat toAlpha = 0.0f; 145 | 146 | [to getHue:&toHue saturation:&toSaturation brightness:&toBrightness alpha:&toAlpha]; 147 | 148 | CGFloat deltaHue = toHue - fromHue; 149 | CGFloat deltaSaturation = toSaturation - fromSaturation; 150 | CGFloat deltaBrightness = toBrightness - fromBrightness; 151 | CGFloat deltaAlpha = toAlpha - fromAlpha; 152 | 153 | return ^(CGFloat fraction) { 154 | CGFloat hue = fromHue + fraction * deltaHue; 155 | CGFloat saturation = fromSaturation + fraction * deltaSaturation; 156 | CGFloat brightness = fromBrightness + fraction * deltaBrightness; 157 | CGFloat alpha = fromAlpha + fraction * deltaAlpha; 158 | 159 | CGColorRef colorRef = [RBBColor rbb_colorWithHue:hue saturation:saturation brightness:brightness alpha:alpha].CGColor; 160 | 161 | return (__bridge id)colorRef; 162 | }; 163 | } 164 | 165 | extern RBBLinearInterpolation RBBInterpolate(id from, id to) { 166 | if ([from isKindOfClass:NSNumber.class] && [to isKindOfClass:NSNumber.class]) { 167 | #if CGFLOAT_IS_DOUBLE 168 | return RBBInterpolateCGFloat([(NSNumber *)from doubleValue], [(NSNumber *)to doubleValue]); 169 | #else 170 | return RBBInterpolateCGFloat([(NSNumber *)from floatValue], [(NSNumber *)to doubleValue]); 171 | #endif 172 | } 173 | 174 | if ((CFGetTypeID((__bridge CFTypeRef)from) == CGColorGetTypeID()) && (CFGetTypeID((__bridge CFTypeRef)to) == CGColorGetTypeID())) { 175 | RBBColor *fromColor = [RBBColor colorWithCGColor:(CGColorRef)from]; 176 | RBBColor *toColor = [RBBColor colorWithCGColor:(CGColorRef)to]; 177 | 178 | return RBBInterpolateColor(fromColor, toColor); 179 | } 180 | 181 | if (([from isKindOfClass:NSValue.class] && [to isKindOfClass:NSValue.class]) && strcmp([from objCType], [to objCType]) == 0) { 182 | if (strcmp([from objCType], @encode(CATransform3D)) == 0) { 183 | return RBBInterpolateCATransform3D([from CATransform3DValue], [to CATransform3DValue]); 184 | } 185 | 186 | if (strcmp([from objCType], @encode(CGRect)) == 0) { 187 | return RBBInterpolateCGRect([from rbb_CGRectValue], [to rbb_CGRectValue]); 188 | } 189 | 190 | if (strcmp([from objCType], @encode(CGPoint)) == 0) { 191 | return RBBInterpolateCGPoint([from rbb_CGPointValue ], [to rbb_CGPointValue]); 192 | } 193 | 194 | if (strcmp([from objCType], @encode(CGSize)) == 0) { 195 | return RBBInterpolateCGSize([from rbb_CGSizeValue], [to rbb_CGSizeValue]); 196 | } 197 | } 198 | 199 | return ^(CGFloat fraction) { 200 | return fraction < 0.5 ? from : to; 201 | }; 202 | } 203 | -------------------------------------------------------------------------------- /RBBAnimation/RBBSpringAnimation.h: -------------------------------------------------------------------------------- 1 | // 2 | // RBBSpringAnimation.h 3 | // RBBAnimation 4 | // 5 | // Created by Robert Böhnke on 10/14/13. 6 | // Copyright (c) 2013 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "RBBAnimation.h" 12 | 13 | @interface RBBSpringAnimation : RBBAnimation 14 | 15 | @property (readwrite, nonatomic, assign) CGFloat damping; 16 | @property (readwrite, nonatomic, assign) CGFloat mass; 17 | @property (readwrite, nonatomic, assign) CGFloat stiffness; 18 | @property (readwrite, nonatomic, assign) CGFloat velocity; 19 | 20 | @property (readwrite, nonatomic, strong) id fromValue; 21 | @property (readwrite, nonatomic, strong) id toValue; 22 | 23 | @property (readwrite, nonatomic, assign) BOOL allowsOverdamping; 24 | 25 | - (CFTimeInterval)durationForEpsilon:(double)epsilon; 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /RBBAnimation/RBBSpringAnimation.m: -------------------------------------------------------------------------------- 1 | // 2 | // RBBSpringAnimation.m 3 | // RBBAnimation 4 | // 5 | // Created by Robert Böhnke on 10/14/13. 6 | // Copyright (c) 2013 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #import "RBBBlockBasedArray.h" 10 | #import "RBBLinearInterpolation.h" 11 | 12 | #import "RBBSpringAnimation.h" 13 | 14 | @implementation RBBSpringAnimation 15 | 16 | #pragma mark - Lifecycle 17 | 18 | - (id)init { 19 | self = [super init]; 20 | if (self == nil) return nil; 21 | 22 | self.damping = 10; 23 | self.mass = 1; 24 | self.stiffness = 100; 25 | 26 | self.calculationMode = kCAAnimationDiscrete; 27 | 28 | return self; 29 | } 30 | 31 | #pragma mark - KVO 32 | 33 | + (NSSet *)keyPathsForValuesAffectingAnimationBlock { 34 | return [NSSet setWithArray:@[ 35 | @"damping", 36 | @"mass", 37 | @"stiffness", 38 | @"velocity", 39 | @"fromValue", 40 | @"toValue", 41 | @"allowsOverdamping" 42 | ]]; 43 | } 44 | 45 | #pragma mark - RBBSpringAnimation 46 | 47 | - (CFTimeInterval)durationForEpsilon:(double)epsilon { 48 | CGFloat beta = self.damping / (2 * self.mass); 49 | 50 | CFTimeInterval duration = 0; 51 | while (expf(-beta * duration) >= epsilon) { 52 | duration += 0.1; 53 | } 54 | 55 | return duration; 56 | } 57 | 58 | #pragma mark - RBBAnimation 59 | 60 | - (RBBAnimationBlock)animationBlock { 61 | CGFloat b = self.damping; 62 | CGFloat m = self.mass; 63 | CGFloat k = self.stiffness; 64 | CGFloat v0 = self.velocity; 65 | 66 | NSParameterAssert(m > 0); 67 | NSParameterAssert(k > 0); 68 | NSParameterAssert(b > 0); 69 | 70 | CGFloat beta = b / (2 * m); 71 | CGFloat omega0 = sqrtf(k / m); 72 | CGFloat omega1 = sqrtf((omega0 * omega0) - (beta * beta)); 73 | CGFloat omega2 = sqrtf((beta * beta) - (omega0 * omega0)); 74 | 75 | CGFloat x0 = -1; 76 | 77 | if (!self.allowsOverdamping && beta > omega0) beta = omega0; 78 | 79 | CGFloat (^oscillation)(CGFloat); 80 | if (beta < omega0) { 81 | // Underdamped 82 | oscillation = ^(CGFloat t) { 83 | CGFloat envelope = expf(-beta * t); 84 | 85 | return -x0 + envelope * (x0 * cosf(omega1 * t) + ((beta * x0 + v0) / omega1) * sinf(omega1 * t)); 86 | }; 87 | } else if (beta == omega0) { 88 | // Critically damped 89 | oscillation = ^(CGFloat t) { 90 | CGFloat envelope = expf(-beta * t); 91 | 92 | return -x0 + envelope * (x0 + (beta * x0 + v0) * t); 93 | }; 94 | } else { 95 | // Overdamped 96 | oscillation = ^(CGFloat t) { 97 | CGFloat envelope = expf(-beta * t); 98 | 99 | return -x0 + envelope * (x0 * coshf(omega2 * t) + ((beta * x0 + v0) / omega2) * sinhf(omega2 * t)); 100 | }; 101 | } 102 | 103 | RBBLinearInterpolation lerp = RBBInterpolate(self.fromValue, self.toValue); 104 | return ^(CGFloat t, CGFloat _) { 105 | return lerp(oscillation(t)); 106 | }; 107 | } 108 | 109 | #pragma mark - NSObject 110 | 111 | - (id)copyWithZone:(NSZone *)zone { 112 | RBBSpringAnimation *copy = [super copyWithZone:zone]; 113 | if (copy == nil) return nil; 114 | 115 | copy->_damping = _damping; 116 | copy->_mass = _mass; 117 | copy->_stiffness = _stiffness; 118 | copy->_velocity = _velocity; 119 | 120 | copy->_fromValue = _fromValue; 121 | copy->_toValue = _toValue; 122 | 123 | copy->_allowsOverdamping = _allowsOverdamping; 124 | 125 | return copy; 126 | } 127 | 128 | @end 129 | -------------------------------------------------------------------------------- /RBBAnimation/RBBTweenAnimation.h: -------------------------------------------------------------------------------- 1 | // 2 | // RBBTweenAnimation.h 3 | // RBBAnimation 4 | // 5 | // Created by Robert Böhnke on 10/13/13. 6 | // Copyright (c) 2013 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #import "RBBAnimation.h" 10 | 11 | #import "RBBEasingFunction.h" 12 | 13 | @interface RBBTweenAnimation : RBBAnimation 14 | 15 | @property (readwrite, nonatomic, strong) NSValue *fromValue; 16 | @property (readwrite, nonatomic, strong) NSValue *toValue; 17 | 18 | @property (readwrite, nonatomic, copy) RBBEasingFunction easing; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /RBBAnimation/RBBTweenAnimation.m: -------------------------------------------------------------------------------- 1 | // 2 | // RBBTweenAnimation.m 3 | // RBBAnimation 4 | // 5 | // Created by Robert Böhnke on 10/13/13. 6 | // Copyright (c) 2013 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | 10 | #import "RBBLinearInterpolation.h" 11 | 12 | #import "RBBTweenAnimation.h" 13 | 14 | @implementation RBBTweenAnimation 15 | 16 | #pragma mark - Lifecycle 17 | 18 | - (id)init { 19 | self = [super init]; 20 | if (self == nil) return nil; 21 | 22 | self.easing = RBBEasingFunctionLinear; 23 | 24 | return self; 25 | } 26 | 27 | #pragma mark - KVO 28 | 29 | + (NSSet *)keyPathsForValuesAffectingAnimationBlock { 30 | return [NSSet setWithArray:@[ @"from", @"to", @"easing" ]]; 31 | } 32 | 33 | #pragma mark - RBBAnimation 34 | 35 | - (RBBAnimationBlock)animationBlock { 36 | NSParameterAssert(self.easing != nil); 37 | 38 | RBBEasingFunction easing = [self.easing copy]; 39 | RBBLinearInterpolation lerp = RBBInterpolate(self.fromValue, self.toValue); 40 | 41 | return ^(CGFloat elapsed, CGFloat duration) { 42 | return lerp(easing(elapsed / duration)); 43 | }; 44 | } 45 | 46 | #pragma mark - NSObject 47 | 48 | - (id)copyWithZone:(NSZone *)zone { 49 | RBBTweenAnimation *copy = [super copyWithZone:zone]; 50 | if (copy == nil) return nil; 51 | 52 | copy->_easing = _easing; 53 | 54 | copy->_fromValue = _fromValue; 55 | copy->_toValue = _toValue; 56 | 57 | return copy; 58 | } 59 | 60 | @end 61 | -------------------------------------------------------------------------------- /RBBAnimation/UIColor+PlatformIndependence.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIColor+PlatformIndependence.h 3 | // RBBAnimation 4 | // 5 | // Created by Robert Böhnke on 11/04/14. 6 | // Copyright (c) 2014 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIColor (PlatformIndependence) 12 | 13 | + (instancetype)rbb_colorWithHue:(CGFloat)hue saturation:(CGFloat)saturation brightness:(CGFloat)brightness alpha:(CGFloat)alpha; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /RBBAnimation/UIColor+PlatformIndependence.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIColor+PlatformIndependence.m 3 | // RBBAnimation 4 | // 5 | // Created by Robert Böhnke on 11/04/14. 6 | // Copyright (c) 2014 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #import "UIColor+PlatformIndependence.h" 10 | 11 | @implementation UIColor (PlatformIndependence) 12 | 13 | + (instancetype)rbb_colorWithHue:(CGFloat)hue saturation:(CGFloat)saturation brightness:(CGFloat)brightness alpha:(CGFloat)alpha { 14 | return [self colorWithHue:hue saturation:saturation brightness:brightness alpha:alpha]; 15 | } 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /RBBAnimationTest/CAAnimation+Name.h: -------------------------------------------------------------------------------- 1 | // 2 | // CAAnimation+Name.h 3 | // RBBAnimation 4 | // 5 | // Created by Robert Böhnke on 10/13/13. 6 | // Copyright (c) 2013 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface CAAnimation (Name) 12 | 13 | @property (readwrite, nonatomic, copy) NSString *rbb_name; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /RBBAnimationTest/CAAnimation+Name.m: -------------------------------------------------------------------------------- 1 | // 2 | // CAAnimation+Name.m 3 | // RBBAnimation 4 | // 5 | // Created by Robert Böhnke on 10/13/13. 6 | // Copyright (c) 2013 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "CAAnimation+Name.h" 12 | 13 | @implementation CAAnimation (Name) 14 | 15 | @synthesizeAssociation(CAAnimation, rbb_name); 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /RBBAnimationTest/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "40x40", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "60x60", 16 | "scale" : "2x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /RBBAnimationTest/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "7.0", 8 | "scale" : "2x" 9 | }, 10 | { 11 | "orientation" : "portrait", 12 | "idiom" : "iphone", 13 | "subtype" : "retina4", 14 | "extent" : "full-screen", 15 | "minimum-system-version" : "7.0", 16 | "scale" : "2x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /RBBAnimationTest/RBBAnimationListViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // RBBAnimationListViewController.h 3 | // RBBAnimation 4 | // 5 | // Created by Robert Böhnke on 10/11/13. 6 | // Copyright (c) 2013 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface RBBAnimationListViewController : UITableViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /RBBAnimationTest/RBBAnimationListViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // RBBAnimationListViewController.m 3 | // RBBAnimation 4 | // 5 | // Created by Robert Böhnke on 10/11/13. 6 | // Copyright (c) 2013 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #import "CAAnimation+Name.h" 10 | #import "RBBAnimation.h" 11 | #import "RBBAnimationViewController.h" 12 | #import "RBBCubicBezier.h" 13 | #import "RBBCustomAnimation.h" 14 | #import "RBBTweenAnimation.h" 15 | #import "RBBSpringAnimation.h" 16 | 17 | #import "RBBAnimationListViewController.h" 18 | 19 | @interface RBBAnimationListViewController () 20 | 21 | @property (readwrite, nonatomic, copy) NSArray *animations; 22 | 23 | @end 24 | 25 | @implementation RBBAnimationListViewController 26 | 27 | #pragma mark - UIViewController 28 | 29 | - (void)viewDidLoad { 30 | [super viewDidLoad]; 31 | 32 | self.title = @"Animations"; 33 | 34 | RBBTweenAnimation *easeInOutBack = [RBBTweenAnimation animationWithKeyPath:@"position.y"]; 35 | 36 | easeInOutBack.fromValue = @(-100.0f); 37 | easeInOutBack.toValue = @(100.0f); 38 | easeInOutBack.easing = RBBCubicBezier(0.68, -0.55, 0.265, 1.55); 39 | 40 | easeInOutBack.additive = YES; 41 | easeInOutBack.duration = 0.6; 42 | easeInOutBack.rbb_name = @"ease in out back"; 43 | 44 | RBBTweenAnimation *scale = [RBBTweenAnimation animationWithKeyPath:@"bounds"]; 45 | 46 | scale.fromValue = [NSValue valueWithCGRect:CGRectMake(0, 0, 0, 0)]; 47 | scale.toValue = [NSValue valueWithCGRect:CGRectMake(0, 0, 100, 100)]; 48 | 49 | scale.additive = YES; 50 | scale.duration = 1; 51 | scale.rbb_name = @"scale"; 52 | 53 | RBBSpringAnimation *spring = [RBBSpringAnimation animationWithKeyPath:@"position.y"]; 54 | 55 | spring.fromValue = @(-100.0f); 56 | spring.toValue = @(100.0f); 57 | spring.mass = 1; 58 | spring.damping = 10; 59 | spring.stiffness = 100; 60 | 61 | spring.additive = YES; 62 | spring.duration = [spring durationForEpsilon:0.01]; 63 | spring.rbb_name = @"spring"; 64 | 65 | RBBTweenAnimation *sinus = [RBBTweenAnimation animationWithKeyPath:@"position.y"]; 66 | sinus.fromValue = @(0); 67 | sinus.toValue = @(100); 68 | sinus.easing = ^CGFloat (CGFloat fraction) { 69 | return sin((fraction) * 2 * M_PI); 70 | }; 71 | 72 | sinus.additive = YES; 73 | sinus.duration = 2; 74 | sinus.rbb_name = @"sine wave"; 75 | 76 | RBBTweenAnimation *bounce = [RBBTweenAnimation animationWithKeyPath:@"position.y"]; 77 | bounce.fromValue = @(-100); 78 | bounce.toValue = @(100); 79 | bounce.easing = RBBEasingFunctionEaseOutBounce; 80 | 81 | bounce.additive = YES; 82 | bounce.duration = 0.8; 83 | bounce.rbb_name = @"bounce"; 84 | 85 | RBBCustomAnimation *rainbow = [RBBCustomAnimation animationWithKeyPath:@"backgroundColor"]; 86 | rainbow.animationBlock = ^(CGFloat elapsed, CGFloat duration) { 87 | return (id)[UIColor colorWithHue:elapsed / duration saturation:1 brightness:1 alpha:1].CGColor; 88 | }; 89 | 90 | rainbow.duration = 5; 91 | rainbow.rbb_name = @"rainbow"; 92 | 93 | self.animations = @[ 94 | easeInOutBack, 95 | spring, 96 | scale, 97 | sinus, 98 | bounce, 99 | rainbow 100 | ]; 101 | } 102 | 103 | #pragma mark - UITableViewDataSource 104 | 105 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 106 | return self.animations.count; 107 | } 108 | 109 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 110 | UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil]; 111 | 112 | RBBAnimation *animation = self.animations[indexPath.row]; 113 | cell.textLabel.text = animation.rbb_name; 114 | 115 | return cell; 116 | } 117 | 118 | #pragma mark - UITableViewDelegate 119 | 120 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 121 | RBBAnimation *animation = self.animations[indexPath.row]; 122 | 123 | RBBAnimationViewController *vc = [[RBBAnimationViewController alloc] initWithAnimation:animation]; 124 | 125 | [self.navigationController pushViewController:vc animated:YES]; 126 | } 127 | 128 | @end 129 | -------------------------------------------------------------------------------- /RBBAnimationTest/RBBAnimationTest-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | com.robertboehnke.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /RBBAnimationTest/RBBAnimationTest-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #import 8 | 9 | #ifndef __IPHONE_3_0 10 | #warning "This project uses features only available in iOS SDK 3.0 and later." 11 | #endif 12 | 13 | #ifdef __OBJC__ 14 | #import 15 | #import 16 | #endif 17 | -------------------------------------------------------------------------------- /RBBAnimationTest/RBBAnimationViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // RBBAnimationViewController.h 3 | // RBBAnimation 4 | // 5 | // Created by Robert Böhnke on 10/11/13. 6 | // Copyright (c) 2013 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface RBBAnimationViewController : UIViewController 12 | 13 | - (instancetype)initWithAnimation:(RBBAnimation *)animation; 14 | 15 | @property (readonly, nonatomic, strong) RBBAnimation *animation; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /RBBAnimationTest/RBBAnimationViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // RBBAnimationViewController.m 3 | // RBBAnimation 4 | // 5 | // Created by Robert Böhnke on 10/11/13. 6 | // Copyright (c) 2013 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #import "RBBAnimation.h" 10 | #import "CAAnimation+Name.h" 11 | 12 | #import "RBBAnimationViewController.h" 13 | 14 | @interface RBBAnimationViewController () 15 | 16 | @property (readwrite, nonatomic, strong) UIView *rectangle; 17 | 18 | @end 19 | 20 | @implementation RBBAnimationViewController 21 | 22 | - (instancetype)initWithAnimation:(RBBAnimation *)animation { 23 | self = [super init]; 24 | if (self == nil) return nil; 25 | 26 | _animation = animation; 27 | self.title = animation.rbb_name; 28 | 29 | return self; 30 | } 31 | 32 | #pragma mark - Properties 33 | 34 | - (void)viewDidLoad { 35 | [super viewDidLoad]; 36 | 37 | self.view.backgroundColor = UIColor.whiteColor; 38 | 39 | self.rectangle = [[UIView alloc] init]; 40 | self.rectangle.backgroundColor = UIColor.redColor; 41 | self.rectangle.bounds = CGRectMake(0, 0, 100, 100); 42 | self.rectangle.center = CGPointMake(CGRectGetMidX(self.view.frame), 43 | CGRectGetMidY(self.view.frame)); 44 | 45 | [self.view addSubview:self.rectangle]; 46 | } 47 | 48 | - (void)viewDidAppear:(BOOL)animated { 49 | [super viewDidAppear:animated]; 50 | 51 | self.animation.repeatCount = HUGE_VALF; 52 | 53 | [self.rectangle.layer addAnimation:self.animation forKey:@"Animation"]; 54 | } 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /RBBAnimationTest/RBBAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // RBBAppDelegate.h 3 | // RBBAnimationTest 4 | // 5 | // Created by Robert Böhnke on 10/11/13. 6 | // Copyright (c) 2013 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface RBBAppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /RBBAnimationTest/RBBAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // RBBAppDelegate.m 3 | // RBBAnimationTest 4 | // 5 | // Created by Robert Böhnke on 10/11/13. 6 | // Copyright (c) 2013 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #import "RBBAnimationListViewController.h" 10 | 11 | #import "RBBAppDelegate.h" 12 | 13 | @implementation RBBAppDelegate 14 | 15 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 16 | { 17 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 18 | 19 | self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:[[RBBAnimationListViewController alloc] init]]; 20 | self.window.backgroundColor = [UIColor whiteColor]; 21 | [self.window makeKeyAndVisible]; 22 | return YES; 23 | } 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /RBBAnimationTest/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /RBBAnimationTest/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // RBBAnimationTest 4 | // 5 | // Created by Robert Böhnke on 10/11/13. 6 | // Copyright (c) 2013 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "RBBAppDelegate.h" 12 | 13 | int main(int argc, char * argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([RBBAppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RBBAnimation 2 | 3 | 4 | 5 | 6 | 7 | `RBBAnimation` is a subclass of `CAKeyframeAnimation` that allows you to 8 | declare your __animations using blocks__ instead of writing out all the 9 | individual key-frames. 10 | 11 | This gives you greater flexibility when specifying your animations while keeping 12 | your code concise. 13 | 14 | It comes out of the box with a [replacement for 15 | CASpringAnimation](#rbbspringanimation), [support for custom easing functions 16 | such as bouncing](#rbbtweenanimation) as well as hooks to allow your writing 17 | your [own animations fully from scratch](#rbbcustomanimation). 18 | 19 | ## Installation 20 | 21 | To install RBBAnimation, I recommend the excellent [CocoaPods]. Simply add this 22 | to your Podfile 23 | 24 | ```ruby 25 | pod 'RBBAnimation', '0.4.0' 26 | ``` 27 | 28 | and you are ready to go! 29 | 30 | If you'd like to run the bundled test app, make sure to install its dependencies 31 | by running 32 | 33 | ```sh 34 | pod install 35 | ``` 36 | 37 | after cloning the repo. 38 | 39 | ## RBBCustomAnimation 40 | 41 | Use `RBBCustomAnimation` to create arbitrary animations by passing in an 42 | `RBBAnimationBlock`: 43 | 44 |

45 | Rainbow 46 |

47 | 48 | ```objc 49 | RBBCustomAnimation *rainbow = [RBBCustomAnimation animationWithKeyPath:@"backgroundColor"]; 50 | 51 | rainbow.animationBlock = ^(CGFloat elapsed, CGFloat duration) { 52 | UIColor *color = [UIColor colorWithHue:elapsed / duration 53 | saturation:1 54 | brightness:1 55 | alpha:1]; 56 | 57 | return (id)color.CGColor; 58 | }; 59 | ``` 60 | 61 | The arguments of the block are the current position of the animation as well as 62 | its total duration. 63 | 64 | Most of the time, you will probably want to use the higher-level 65 | `RBBTweenAnimation`. 66 | 67 | ## RBBSpringAnimation 68 | 69 | `RBBSpringAnimation` is a handy replacement for the private [CASpringAnimation]. 70 | Specify your spring's mass, damping, stiffness as well as its initial velocity 71 | and watch it go: 72 | 73 |

74 | Bouncing 75 |

76 | 77 | ```objc 78 | RBBSpringAnimation *spring = [RBBSpringAnimation animationWithKeyPath:@"position.y"]; 79 | 80 | spring.fromValue = @(-100.0f); 81 | spring.toValue = @(100.0f); 82 | spring.velocity = 0; 83 | spring.mass = 1; 84 | spring.damping = 10; 85 | spring.stiffness = 100; 86 | 87 | spring.additive = YES; 88 | spring.duration = [spring durationForEpsilon:0.01]; 89 | ``` 90 | 91 | ## RBBTweenAnimation 92 | 93 | `RBBTweenAnimation` allows you to animate from one value to another, similar to 94 | `CABasicAnimation` but with a greater flexibility in how the values should be 95 | interpolated. 96 | 97 | It supports the same cubic Bezier interpolation that you get from 98 | `CAMediaTimingFunction` using the `RBBCubicBezier` helper function: 99 | 100 |

101 | Ease In Out Back 102 |

103 | 104 | ```objc 105 | RBBTweenAnimation *easeInOutBack = [RBBTweenAnimation animationWithKeyPath:@"position.y"]; 106 | 107 | easeInOutBack.fromValue = @(-100.0f); 108 | easeInOutBack.toValue = @(100.0f); 109 | easeInOutBack.easing = RBBCubicBezier(0.68, -0.55, 0.265, 1.55); 110 | 111 | easeInOutBack.additive = YES; 112 | easeInOutBack.duration = 0.6; 113 | ``` 114 | 115 | However, `RBBTweenAnimation` also supports more complex easing functions such as 116 | `RBBEasingFunctionEaseOutBounce`: 117 | 118 |

119 | Bouncing 120 |

121 | 122 | ```objc 123 | RBBTweenAnimation *bounce = [RBBTweenAnimation animationWithKeyPath:@"position.y"]; 124 | bounce.fromValue = @(-100); 125 | bounce.toValue = @(100); 126 | bounce.easing = RBBEasingFunctionEaseOutBounce; 127 | 128 | bounce.additive = YES; 129 | bounce.duration = 0.8; 130 | ``` 131 | 132 | You can also specify your own easing functions, from scratch: 133 | 134 | ```objc 135 | RBBTweenAnimation *sinus = [RBBTweenAnimation animationWithKeyPath:@"position.y"]; 136 | sinus.fromValue = @(0); 137 | sinus.toValue = @(100); 138 | 139 | sinus.easing = ^CGFloat (CGFloat fraction) { 140 | return sin((fraction) * 2 * M_PI); 141 | }; 142 | 143 | sinus.additive = YES; 144 | sinus.duration = 2; 145 | ``` 146 | 147 |

148 | Sine Wave 149 |

150 | 151 | ## License 152 | 153 | RBBAnimation was built by [Robert Böhnke][robb]. It is licensed under the MIT 154 | License. 155 | 156 | If you use RBBAnimation in one of your apps, I'd love to hear about it. Feel 157 | free to follow me on Twitter where I'm [@ceterum_censeo][twitter]. 158 | 159 | [caspringanimation]: https://github.com/nst/iOS-Runtime-Headers/blob/master/Frameworks/QuartzCore.framework/CASpringAnimation.h 160 | [robb]: http://robb.is 161 | [twitter]: https://twitter.com/ceterum_censeo 162 | [cocoapods]: http://cocoapods.org/ 163 | -------------------------------------------------------------------------------- /Specs/RBBBlockBasedArraySpec.m: -------------------------------------------------------------------------------- 1 | // 2 | // RBBBlockBasedArraySpec.m 3 | // RBBAnimation 4 | // 5 | // Created by Robert Böhnke on 10/11/13. 6 | // Copyright (c) 2013 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #import "RBBBlockBasedArray.h" 10 | 11 | SpecBegin(RBBBlockBasedArray) 12 | 13 | describe(@"A block-based array", ^{ 14 | __block NSArray *array; 15 | 16 | beforeEach(^{ 17 | array = [RBBBlockBasedArray arrayWithCount:5 block:^(NSUInteger idx) { 18 | return @(idx); 19 | }]; 20 | }); 21 | 22 | it(@"should have a count", ^{ 23 | expect(array).to.haveCountOf(5); 24 | }); 25 | 26 | it(@"should allow access to elements", ^{ 27 | expect(array[0]).to.equal(@0); 28 | expect(array[2]).to.equal(@2); 29 | }); 30 | 31 | it(@"should equal existing 'normal' arrays", ^{ 32 | expect(array).to.equal((@[ @0, @1, @2, @3, @4 ])); 33 | 34 | expect((@[ @0, @1, @2, @3, @4 ])).to.equal(array); 35 | }); 36 | 37 | it(@"should support -firstObject", ^{ 38 | expect(array.firstObject).to.equal(@0); 39 | }); 40 | 41 | it(@"should support -lastObject", ^{ 42 | expect(array.lastObject).to.equal(@4); 43 | }); 44 | }); 45 | 46 | it(@"should initialize with a count and a block", ^{ 47 | NSArray *array = [RBBBlockBasedArray arrayWithCount:2 block:^(NSUInteger idx) { 48 | return @(idx); 49 | }]; 50 | 51 | expect(array).notTo.beNil(); 52 | }); 53 | 54 | it(@"should initialize", ^{ 55 | NSArray *array = [[RBBBlockBasedArray alloc] init]; 56 | 57 | expect(array).notTo.beNil(); 58 | expect(array).to.equal(@[]); 59 | }); 60 | 61 | it(@"should intialize with objects and a count", ^{ 62 | id objects[3] = { @1, @2, @3 }; 63 | 64 | NSArray *array = [[RBBBlockBasedArray alloc] initWithObjects:objects count:3]; 65 | 66 | expect(array).notTo.beNil(); 67 | expect(array).to.equal((@[ @1, @2, @3 ])); 68 | }); 69 | 70 | SpecEnd 71 | -------------------------------------------------------------------------------- /Specs/RBBLinearInterpolationSpec.m: -------------------------------------------------------------------------------- 1 | // 2 | // RBBLinearInterpolationSpec.m 3 | // RBBAnimation 4 | // 5 | // Created by Robert Böhnke on 11/04/14. 6 | // Copyright (c) 2014 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR 10 | #import 11 | 12 | #import "UIColor+PlatformIndependence.h" 13 | 14 | #define SpecsColor UIColor 15 | #else 16 | #import 17 | 18 | #import "NSColor+PlatformIndependence.h" 19 | 20 | #define SpecsColor NSColor 21 | #endif 22 | 23 | #import "NSValue+PlatformIndependence.h" 24 | 25 | #import "RBBLinearInterpolation.h" 26 | 27 | SpecBegin(RBBLinearInterpolation) 28 | 29 | __block RBBLinearInterpolation lerp; 30 | 31 | describe(@"Interpolating numbers", ^{ 32 | it(@"should interpolate them as floats", ^{ 33 | lerp = RBBInterpolate(@2, @4); 34 | 35 | expect(lerp(0.5)).to.beCloseToWithin(3, 0.01); 36 | }); 37 | }); 38 | 39 | describe(@"Interpolating colors", ^{ 40 | it(@"should interpolate HSBA components separately", ^{ 41 | CGColorRef from = [SpecsColor rbb_colorWithHue:0.2 saturation:0.3 brightness:0.4 alpha:0.5].CGColor; 42 | CGColorRef to = [SpecsColor rbb_colorWithHue:0.4 saturation:0.5 brightness:0.6 alpha:0.7].CGColor; 43 | 44 | lerp = RBBInterpolate((__bridge id)from, (__bridge id)to); 45 | 46 | CGFloat hue, saturation, brightness, alpha; 47 | 48 | SpecsColor *color = [SpecsColor colorWithCGColor:(__bridge CGColorRef)lerp(0.5)]; 49 | [color getHue:&hue saturation:&saturation brightness:&brightness alpha:&alpha]; 50 | 51 | expect(hue).to.beCloseToWithin(0.3, 0.01); 52 | expect(saturation).to.beCloseToWithin(0.4, 0.01); 53 | expect(brightness).to.beCloseToWithin(0.5, 0.01); 54 | expect(alpha).to.beCloseToWithin(0.6, 0.01); 55 | }); 56 | }); 57 | 58 | describe(@"Interpolating CATransform3D", ^{ 59 | it(@"should interpolate every entry separately", ^{ 60 | CATransform3D from = { 61 | 1, 2, 3, 4, 62 | 5, 6, 7, 8, 63 | 9, 10, 11, 12, 64 | 13, 14, 15, 16 65 | }; 66 | 67 | CATransform3D to = { 68 | 3, 4, 5, 6, 69 | 7, 8, 9, 10, 70 | 11, 12, 13, 14, 71 | 15, 16, 17, 18 72 | }; 73 | 74 | lerp = RBBInterpolate([NSValue valueWithCATransform3D:from], [NSValue valueWithCATransform3D:to]); 75 | 76 | CATransform3D transform = [lerp(0.5) CATransform3DValue]; 77 | 78 | expect(transform.m11).to.beCloseToWithin( 2, 0.01); 79 | expect(transform.m12).to.beCloseToWithin( 3, 0.01); 80 | expect(transform.m13).to.beCloseToWithin( 4, 0.01); 81 | expect(transform.m14).to.beCloseToWithin( 5, 0.01); 82 | expect(transform.m21).to.beCloseToWithin( 6, 0.01); 83 | expect(transform.m22).to.beCloseToWithin( 7, 0.01); 84 | expect(transform.m23).to.beCloseToWithin( 8, 0.01); 85 | expect(transform.m24).to.beCloseToWithin( 9, 0.01); 86 | expect(transform.m31).to.beCloseToWithin(10, 0.01); 87 | expect(transform.m32).to.beCloseToWithin(11, 0.01); 88 | expect(transform.m33).to.beCloseToWithin(12, 0.01); 89 | expect(transform.m34).to.beCloseToWithin(13, 0.01); 90 | expect(transform.m41).to.beCloseToWithin(14, 0.01); 91 | expect(transform.m42).to.beCloseToWithin(15, 0.01); 92 | expect(transform.m43).to.beCloseToWithin(16, 0.01); 93 | expect(transform.m44).to.beCloseToWithin(17, 0.01); 94 | }); 95 | }); 96 | 97 | describe(@"Interpolating CGRects", ^{ 98 | it(@"should should interpolate size and origin separately", ^{ 99 | CGRect from = CGRectMake(1, 2, 3, 4); 100 | CGRect to = CGRectMake(5, 6, 7, 8); 101 | 102 | lerp = RBBInterpolate([NSValue rbb_valueWithCGRect:from], [NSValue rbb_valueWithCGRect:to]); 103 | 104 | expect(lerp(0.5)).to.equal([NSValue rbb_valueWithCGRect:CGRectMake(3, 4, 5, 6)]); 105 | }); 106 | }); 107 | 108 | describe(@"Interpolating CGPoints", ^{ 109 | it(@"should should interpolate x and y", ^{ 110 | CGPoint from = CGPointMake(1, 2); 111 | CGPoint to = CGPointMake(5, 6); 112 | 113 | lerp = RBBInterpolate([NSValue rbb_valueWithCGPoint:from], [NSValue rbb_valueWithCGPoint:to]); 114 | 115 | expect(lerp(0.5)).to.equal([NSValue rbb_valueWithCGPoint:CGPointMake(3, 4)]); 116 | }); 117 | }); 118 | 119 | describe(@"Interpolating CGSizes", ^{ 120 | it(@"should should interpolate x and y", ^{ 121 | CGSize from = CGSizeMake(1, 2); 122 | CGSize to = CGSizeMake(5, 6); 123 | 124 | lerp = RBBInterpolate([NSValue rbb_valueWithCGSize:from], [NSValue rbb_valueWithCGSize:to]); 125 | 126 | expect(lerp(0.5)).to.equal([NSValue rbb_valueWithCGSize:CGSizeMake(3, 4)]); 127 | }); 128 | }); 129 | 130 | describe(@"Interpolating mismatched value types", ^{ 131 | it(@"should change between both input values", ^{ 132 | NSValue *from = [NSValue rbb_valueWithCGPoint:CGPointMake(1, 2)]; 133 | NSValue *to = [NSValue rbb_valueWithCGRect:CGRectMake(5, 6, 7, 8)]; 134 | 135 | lerp = RBBInterpolate(from, to); 136 | 137 | expect(lerp(0.25)).to.equal(from); 138 | expect(lerp(0.75)).to.equal(to); 139 | }); 140 | }); 141 | 142 | describe(@"Interpolating anything else", ^{ 143 | it(@"should change between both input values", ^{ 144 | lerp = RBBInterpolate(@"foo", @"bar"); 145 | 146 | expect(lerp(0.25)).to.equal(@"foo"); 147 | expect(lerp(0.75)).to.equal(@"bar"); 148 | }); 149 | }); 150 | 151 | SpecEnd 152 | -------------------------------------------------------------------------------- /Specs/RBBSpringAnimationSpec.m: -------------------------------------------------------------------------------- 1 | // 2 | // RBBSpringAnimationSpec.m 3 | // RBBAnimation 4 | // 5 | // Created by Robert Böhnke on 10/04/14. 6 | // Copyright (c) 2014 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #import "RBBSpringAnimation.h" 10 | 11 | @interface CALayer (Private) 12 | 13 | // Here be dragons 14 | - (CALayer *)layerAtTime:(NSTimeInterval)time; 15 | 16 | @end 17 | 18 | SpecBegin(RBBSpringAnimation) 19 | 20 | it(@"should initialize", ^{ 21 | expect([RBBSpringAnimation animation]).notTo.beNil(); 22 | 23 | expect([RBBSpringAnimation animationWithKeyPath:@"position"]).notTo.beNil(); 24 | }); 25 | 26 | it(@"should default to not allow overdamping", ^{ 27 | RBBSpringAnimation *animation = [RBBSpringAnimation animation]; 28 | 29 | expect(animation.allowsOverdamping).to.beFalsy(); 30 | }); 31 | 32 | describe(@"compared to CASpringAnimation", ^{ 33 | __block RBBSpringAnimation *RBBSpring, *CASpring; 34 | 35 | beforeEach(^{ 36 | RBBSpring = [RBBSpringAnimation animation]; 37 | expect(RBBSpring).toNot.beNil(); 38 | 39 | CASpring = [NSClassFromString(@"CASpringAnimation") animation]; 40 | expect(CASpring).toNot.beNil(); 41 | }); 42 | 43 | it(@"should have the same default values", ^{ 44 | expect(RBBSpring.damping).to.equal(CASpring.damping); 45 | expect(RBBSpring.mass).to.equal(CASpring.mass); 46 | expect(RBBSpring.stiffness).to.equal(CASpring.stiffness); 47 | expect(RBBSpring.velocity).to.equal(CASpring.velocity); 48 | }); 49 | 50 | describe(@"when run on a layer", ^{ 51 | __block CALayer *a, *b; 52 | 53 | beforeEach(^{ 54 | for (RBBSpringAnimation *animation in @[ RBBSpring, CASpring ]) { 55 | animation.keyPath = @"position.x"; 56 | animation.velocity = 5; 57 | animation.fromValue = @100; 58 | animation.toValue = @200; 59 | 60 | animation.duration = 1; 61 | animation.beginTime = 0; 62 | } 63 | 64 | a = [CALayer layer]; 65 | b = [CALayer layer]; 66 | 67 | a.speed = 0; 68 | b.speed = 0; 69 | 70 | [a addAnimation:RBBSpring forKey:@"spring"]; 71 | [b addAnimation:CASpring forKey:@"spring"]; 72 | }); 73 | 74 | it(@"should have similar values to CASpringAnimation", ^{ 75 | for (NSUInteger frame = 0; frame < 60; frame++) { 76 | CGFloat value = [a layerAtTime:a.beginTime + frame / 60.0].position.x; 77 | CGFloat expected = [b layerAtTime:b.beginTime + frame / 60.0].position.x; 78 | 79 | expect(value).to.beCloseToWithin(expected, 0.001); 80 | } 81 | }); 82 | }); 83 | }); 84 | 85 | SpecEnd 86 | -------------------------------------------------------------------------------- /Specs/Specs-Prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | 4 | #import 5 | 6 | #define EXP_SHORTHAND 7 | #import 8 | #endif 9 | --------------------------------------------------------------------------------