From c8bd9b74357a01f9f06bb2ffbc66eb1323523632 Mon Sep 17 00:00:00 2001 From: Giuseppe Nucifora Date: Wed, 15 Jul 2015 18:26:19 +0200 Subject: [PATCH] Release 0.1.0 --- Example/Podfile | 2 + Example/Podfile.lock | 27 + .../FBSnapshotTestCase/FBSnapshotTestCase.h | 127 ++ .../FBSnapshotTestCase/FBSnapshotTestCase.m | 86 + .../FBSnapshotTestCasePlatform.h | 36 + .../FBSnapshotTestCasePlatform.m | 31 + .../FBSnapshotTestController.h | 154 ++ .../FBSnapshotTestController.m | 384 ++++ .../FBSnapshotTestCase/SwiftSupport.swift | 58 + .../FBSnapshotTestCase/UIImage+Compare.h | 37 + .../FBSnapshotTestCase/UIImage+Compare.m | 134 ++ .../FBSnapshotTestCase/UIImage+Diff.h | 37 + .../FBSnapshotTestCase/UIImage+Diff.m | 56 + Example/Pods/FBSnapshotTestCase/LICENSE | 29 + Example/Pods/FBSnapshotTestCase/README.md | 97 + .../FBSnapshotTestCase/FBSnapshotTestCase.h | 1 + .../FBSnapshotTestCasePlatform.h | 1 + .../FBSnapshotTestController.h | 1 + .../FBSnapshotTestCase/UIImage+Compare.h | 1 + .../Private/FBSnapshotTestCase/UIImage+Diff.h | 1 + .../Private/PureLayout/ALView+PureLayout.h | 1 + .../Private/PureLayout/NSArray+PureLayout.h | 1 + .../NSLayoutConstraint+PureLayout.h | 1 + .../Private/PureLayout/PureLayout+Internal.h | 1 + .../Headers/Private/PureLayout/PureLayout.h | 1 + .../Private/PureLayout/PureLayoutDefines.h | 1 + .../Headers/Private/TabBarPicker/TabBarItem.h | 1 + .../Private/TabBarPicker/TabBarPicker.h | 1 + .../Private/TabBarPicker/TabBarSubItem.h | 1 + .../Headers/Private/pop/FloatConversion.h | 1 + Example/Pods/Headers/Private/pop/POP.h | 1 + Example/Pods/Headers/Private/pop/POPAction.h | 1 + .../Private/pop/POPAnimatableProperty.h | 1 + .../Pods/Headers/Private/pop/POPAnimation.h | 1 + .../Headers/Private/pop/POPAnimationEvent.h | 1 + .../Private/pop/POPAnimationEventInternal.h | 1 + .../Headers/Private/pop/POPAnimationExtras.h | 1 + .../Private/pop/POPAnimationInternal.h | 1 + .../Headers/Private/pop/POPAnimationPrivate.h | 1 + .../Headers/Private/pop/POPAnimationRuntime.h | 1 + .../Headers/Private/pop/POPAnimationTracer.h | 1 + .../Private/pop/POPAnimationTracerInternal.h | 1 + .../Pods/Headers/Private/pop/POPAnimator.h | 1 + .../Headers/Private/pop/POPAnimatorPrivate.h | 1 + .../Headers/Private/pop/POPBasicAnimation.h | 1 + .../Private/pop/POPBasicAnimationInternal.h | 1 + Example/Pods/Headers/Private/pop/POPCGUtils.h | 1 + .../Headers/Private/pop/POPCustomAnimation.h | 1 + .../Headers/Private/pop/POPDecayAnimation.h | 1 + .../Private/pop/POPDecayAnimationInternal.h | 1 + Example/Pods/Headers/Private/pop/POPDefines.h | 1 + .../Pods/Headers/Private/pop/POPGeometry.h | 1 + .../Pods/Headers/Private/pop/POPLayerExtras.h | 1 + Example/Pods/Headers/Private/pop/POPMath.h | 1 + .../Private/pop/POPPropertyAnimation.h | 1 + .../pop/POPPropertyAnimationInternal.h | 1 + .../Headers/Private/pop/POPSpringAnimation.h | 1 + .../Private/pop/POPSpringAnimationInternal.h | 1 + .../Headers/Private/pop/POPSpringSolver.h | 1 + Example/Pods/Headers/Private/pop/POPVector.h | 1 + .../Private/pop/TransformationMatrix.h | 1 + Example/Pods/Headers/Private/pop/UnitBezier.h | 1 + .../FBSnapshotTestCase/FBSnapshotTestCase.h | 1 + .../FBSnapshotTestCasePlatform.h | 1 + .../FBSnapshotTestController.h | 1 + .../FBSnapshotTestCase/UIImage+Compare.h | 1 + .../Public/FBSnapshotTestCase/UIImage+Diff.h | 1 + .../Public/PureLayout/ALView+PureLayout.h | 1 + .../Public/PureLayout/NSArray+PureLayout.h | 1 + .../NSLayoutConstraint+PureLayout.h | 1 + .../Public/PureLayout/PureLayout+Internal.h | 1 + .../Headers/Public/PureLayout/PureLayout.h | 1 + .../Public/PureLayout/PureLayoutDefines.h | 1 + .../Headers/Public/TabBarPicker/TabBarItem.h | 1 + .../Public/TabBarPicker/TabBarPicker.h | 1 + .../Public/TabBarPicker/TabBarSubItem.h | 1 + Example/Pods/Headers/Public/pop/POP.h | 1 + .../Public/pop/POPAnimatableProperty.h | 1 + .../Pods/Headers/Public/pop/POPAnimation.h | 1 + .../Headers/Public/pop/POPAnimationEvent.h | 1 + .../Headers/Public/pop/POPAnimationExtras.h | 1 + .../Headers/Public/pop/POPAnimationTracer.h | 1 + Example/Pods/Headers/Public/pop/POPAnimator.h | 1 + .../Headers/Public/pop/POPBasicAnimation.h | 1 + .../Headers/Public/pop/POPCustomAnimation.h | 1 + .../Headers/Public/pop/POPDecayAnimation.h | 1 + Example/Pods/Headers/Public/pop/POPDefines.h | 1 + Example/Pods/Headers/Public/pop/POPGeometry.h | 1 + .../Pods/Headers/Public/pop/POPLayerExtras.h | 1 + .../Headers/Public/pop/POPPropertyAnimation.h | 1 + .../Headers/Public/pop/POPSpringAnimation.h | 1 + .../Local Podspecs/TabBarPicker.podspec.json | 25 + Example/Pods/Manifest.lock | 27 + Example/Pods/Pods.xcodeproj/project.pbxproj | 1815 +++++++++++++++++ ...Example-TabBarPicker-TabBarPicker.xcscheme | 59 + ...TabBarPicker_Example-TabBarPicker.xcscheme | 59 + ...r_Tests-TabBarPicker-TabBarPicker.xcscheme | 59 + ...s-TabBarPicker_Tests-TabBarPicker.xcscheme | 59 + Example/Pods/PureLayout/LICENSE | 9 + .../PureLayout/PureLayout/ALView+PureLayout.h | 253 +++ .../PureLayout/PureLayout/ALView+PureLayout.m | 1102 ++++++++++ .../PureLayout/NSArray+PureLayout.h | 107 + .../PureLayout/NSArray+PureLayout.m | 506 +++++ .../NSLayoutConstraint+PureLayout.h | 58 + .../NSLayoutConstraint+PureLayout.m | 314 +++ .../PureLayout/PureLayout+Internal.h | 78 + .../PureLayout/PureLayout/PureLayout.h | 36 + .../PureLayout/PureLayout/PureLayoutDefines.h | 206 ++ Example/Pods/PureLayout/README.md | 148 ++ .../Info.plist | 26 + ...cker_Example-TabBarPicker-Private.xcconfig | 9 + ...-TabBarPicker_Example-TabBarPicker-dummy.m | 5 + ...bBarPicker_Example-TabBarPicker-prefix.pch | 5 + ...bBarPicker_Example-TabBarPicker-umbrella.h | 9 + ...abBarPicker_Example-TabBarPicker.modulemap | 6 + ...TabBarPicker_Example-TabBarPicker.xcconfig | 0 .../Pods-TabBarPicker_Example/Info.plist | 26 + ...arPicker_Example-acknowledgements.markdown | 26 + ...abBarPicker_Example-acknowledgements.plist | 56 + .../Pods-TabBarPicker_Example-dummy.m | 5 + .../Pods-TabBarPicker_Example-environment.h | 14 + .../Pods-TabBarPicker_Example-frameworks.sh | 55 + .../Pods-TabBarPicker_Example-resources.sh | 93 + .../Pods-TabBarPicker_Example-umbrella.h | 6 + .../Pods-TabBarPicker_Example.debug.xcconfig | 8 + .../Pods-TabBarPicker_Example.modulemap | 6 + ...Pods-TabBarPicker_Example.release.xcconfig | 8 + .../Info.plist | 26 + ..._Tests-FBSnapshotTestCase-Private.xcconfig | 10 + ...BarPicker_Tests-FBSnapshotTestCase-dummy.m | 5 + ...Picker_Tests-FBSnapshotTestCase-prefix.pch | 5 + ...Picker_Tests-FBSnapshotTestCase-umbrella.h | 13 + ...rPicker_Tests-FBSnapshotTestCase.modulemap | 10 + ...arPicker_Tests-FBSnapshotTestCase.xcconfig | 2 + .../Info.plist | 26 + ...arPicker_Tests-PureLayout-Private.xcconfig | 9 + ...Pods-TabBarPicker_Tests-PureLayout-dummy.m | 5 + ...s-TabBarPicker_Tests-PureLayout-prefix.pch | 5 + ...s-TabBarPicker_Tests-PureLayout-umbrella.h | 12 + ...ds-TabBarPicker_Tests-PureLayout.modulemap | 6 + ...ods-TabBarPicker_Tests-PureLayout.xcconfig | 0 .../Info.plist | 26 + ...Picker_Tests-TabBarPicker-Private.xcconfig | 9 + ...ds-TabBarPicker_Tests-TabBarPicker-dummy.m | 5 + ...TabBarPicker_Tests-TabBarPicker-prefix.pch | 5 + ...TabBarPicker_Tests-TabBarPicker-umbrella.h | 9 + ...-TabBarPicker_Tests-TabBarPicker.modulemap | 6 + ...s-TabBarPicker_Tests-TabBarPicker.xcconfig | 0 .../Pods-TabBarPicker_Tests-pop/Info.plist | 26 + ...ds-TabBarPicker_Tests-pop-Private.xcconfig | 11 + .../Pods-TabBarPicker_Tests-pop-dummy.m | 5 + .../Pods-TabBarPicker_Tests-pop-prefix.pch | 5 + .../Pods-TabBarPicker_Tests-pop-umbrella.h | 21 + .../Pods-TabBarPicker_Tests-pop.modulemap | 6 + .../Pods-TabBarPicker_Tests-pop.xcconfig | 3 + .../Pods-TabBarPicker_Tests/Info.plist | 26 + ...bBarPicker_Tests-acknowledgements.markdown | 106 + ...-TabBarPicker_Tests-acknowledgements.plist | 148 ++ .../Pods-TabBarPicker_Tests-dummy.m | 5 + .../Pods-TabBarPicker_Tests-environment.h | 44 + .../Pods-TabBarPicker_Tests-frameworks.sh | 61 + .../Pods-TabBarPicker_Tests-resources.sh | 93 + .../Pods-TabBarPicker_Tests-umbrella.h | 6 + .../Pods-TabBarPicker_Tests.debug.xcconfig | 9 + .../Pods-TabBarPicker_Tests.modulemap | 6 + .../Pods-TabBarPicker_Tests.release.xcconfig | 9 + Example/Pods/pop/LICENSE | 30 + Example/Pods/pop/README.md | 170 ++ Example/Pods/pop/pop/POP.h | 28 + Example/Pods/pop/pop/POPAction.h | 66 + Example/Pods/pop/pop/POPAnimatableProperty.h | 191 ++ Example/Pods/pop/pop/POPAnimatableProperty.mm | 849 ++++++++ Example/Pods/pop/pop/POPAnimation.h | 162 ++ Example/Pods/pop/pop/POPAnimation.mm | 269 +++ Example/Pods/pop/pop/POPAnimationEvent.h | 69 + Example/Pods/pop/pop/POPAnimationEvent.mm | 108 + .../Pods/pop/pop/POPAnimationEventInternal.h | 41 + Example/Pods/pop/pop/POPAnimationExtras.h | 43 + Example/Pods/pop/pop/POPAnimationExtras.mm | 117 ++ Example/Pods/pop/pop/POPAnimationInternal.h | 480 +++++ Example/Pods/pop/pop/POPAnimationPrivate.h | 16 + Example/Pods/pop/pop/POPAnimationRuntime.h | 101 + Example/Pods/pop/pop/POPAnimationRuntime.mm | 288 +++ Example/Pods/pop/pop/POPAnimationTracer.h | 60 + Example/Pods/pop/pop/POPAnimationTracer.mm | 191 ++ .../Pods/pop/pop/POPAnimationTracerInternal.h | 96 + Example/Pods/pop/pop/POPAnimator.h | 47 + Example/Pods/pop/pop/POPAnimator.mm | 794 +++++++ Example/Pods/pop/pop/POPAnimatorPrivate.h | 68 + Example/Pods/pop/pop/POPBasicAnimation.h | 71 + Example/Pods/pop/pop/POPBasicAnimation.mm | 90 + .../Pods/pop/pop/POPBasicAnimationInternal.h | 96 + Example/Pods/pop/pop/POPCGUtils.h | 107 + Example/Pods/pop/pop/POPCGUtils.mm | 96 + Example/Pods/pop/pop/POPCustomAnimation.h | 46 + Example/Pods/pop/pop/POPCustomAnimation.mm | 56 + Example/Pods/pop/pop/POPDecayAnimation.h | 66 + Example/Pods/pop/pop/POPDecayAnimation.mm | 181 ++ .../Pods/pop/pop/POPDecayAnimationInternal.h | 158 ++ Example/Pods/pop/pop/POPDefines.h | 29 + Example/Pods/pop/pop/POPGeometry.h | 73 + Example/Pods/pop/pop/POPGeometry.mm | 67 + Example/Pods/pop/pop/POPLayerExtras.h | 196 ++ Example/Pods/pop/pop/POPLayerExtras.mm | 288 +++ Example/Pods/pop/pop/POPMath.h | 55 + Example/Pods/pop/pop/POPMath.mm | 82 + Example/Pods/pop/pop/POPPropertyAnimation.h | 65 + Example/Pods/pop/pop/POPPropertyAnimation.mm | 105 + .../pop/pop/POPPropertyAnimationInternal.h | 353 ++++ Example/Pods/pop/pop/POPSpringAnimation.h | 67 + Example/Pods/pop/pop/POPSpringAnimation.mm | 164 ++ .../Pods/pop/pop/POPSpringAnimationInternal.h | 130 ++ Example/Pods/pop/pop/POPSpringSolver.h | 190 ++ Example/Pods/pop/pop/POPVector.h | 375 ++++ Example/Pods/pop/pop/POPVector.mm | 301 +++ .../Pods/pop/pop/WebCore/FloatConversion.h | 56 + .../pop/pop/WebCore/TransformationMatrix.cpp | 1072 ++++++++++ .../pop/pop/WebCore/TransformationMatrix.h | 277 +++ Example/Pods/pop/pop/WebCore/UnitBezier.h | 123 ++ .../TabBarPicker.xcodeproj/project.pbxproj | 12 +- .../contents.xcworkspacedata | 10 + .../TabBarPicker/TabBarPickerAppDelegate.m | 3 + .../TabBarPicker/TabBarPickerViewController.m | 34 + Pod/Classes/TabBarItem.h | 41 + Pod/Classes/TabBarItem.m | 31 + Pod/Classes/TabBarPicker.h | 41 + Pod/Classes/TabBarPicker.m | 31 + Pod/Classes/TabBarSubItem.h | 17 + Pod/Classes/TabBarSubItem.m | 28 + TabBarPicker.podspec | 13 +- 230 files changed, 17003 insertions(+), 15 deletions(-) create mode 100644 Example/Podfile.lock create mode 100644 Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestCase.h create mode 100644 Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestCase.m create mode 100644 Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestCasePlatform.h create mode 100644 Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestCasePlatform.m create mode 100644 Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestController.h create mode 100644 Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestController.m create mode 100644 Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/SwiftSupport.swift create mode 100644 Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/UIImage+Compare.h create mode 100644 Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/UIImage+Compare.m create mode 100644 Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/UIImage+Diff.h create mode 100644 Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/UIImage+Diff.m create mode 100644 Example/Pods/FBSnapshotTestCase/LICENSE create mode 100644 Example/Pods/FBSnapshotTestCase/README.md create mode 120000 Example/Pods/Headers/Private/FBSnapshotTestCase/FBSnapshotTestCase.h create mode 120000 Example/Pods/Headers/Private/FBSnapshotTestCase/FBSnapshotTestCasePlatform.h create mode 120000 Example/Pods/Headers/Private/FBSnapshotTestCase/FBSnapshotTestController.h create mode 120000 Example/Pods/Headers/Private/FBSnapshotTestCase/UIImage+Compare.h create mode 120000 Example/Pods/Headers/Private/FBSnapshotTestCase/UIImage+Diff.h create mode 120000 Example/Pods/Headers/Private/PureLayout/ALView+PureLayout.h create mode 120000 Example/Pods/Headers/Private/PureLayout/NSArray+PureLayout.h create mode 120000 Example/Pods/Headers/Private/PureLayout/NSLayoutConstraint+PureLayout.h create mode 120000 Example/Pods/Headers/Private/PureLayout/PureLayout+Internal.h create mode 120000 Example/Pods/Headers/Private/PureLayout/PureLayout.h create mode 120000 Example/Pods/Headers/Private/PureLayout/PureLayoutDefines.h create mode 120000 Example/Pods/Headers/Private/TabBarPicker/TabBarItem.h create mode 120000 Example/Pods/Headers/Private/TabBarPicker/TabBarPicker.h create mode 120000 Example/Pods/Headers/Private/TabBarPicker/TabBarSubItem.h create mode 120000 Example/Pods/Headers/Private/pop/FloatConversion.h create mode 120000 Example/Pods/Headers/Private/pop/POP.h create mode 120000 Example/Pods/Headers/Private/pop/POPAction.h create mode 120000 Example/Pods/Headers/Private/pop/POPAnimatableProperty.h create mode 120000 Example/Pods/Headers/Private/pop/POPAnimation.h create mode 120000 Example/Pods/Headers/Private/pop/POPAnimationEvent.h create mode 120000 Example/Pods/Headers/Private/pop/POPAnimationEventInternal.h create mode 120000 Example/Pods/Headers/Private/pop/POPAnimationExtras.h create mode 120000 Example/Pods/Headers/Private/pop/POPAnimationInternal.h create mode 120000 Example/Pods/Headers/Private/pop/POPAnimationPrivate.h create mode 120000 Example/Pods/Headers/Private/pop/POPAnimationRuntime.h create mode 120000 Example/Pods/Headers/Private/pop/POPAnimationTracer.h create mode 120000 Example/Pods/Headers/Private/pop/POPAnimationTracerInternal.h create mode 120000 Example/Pods/Headers/Private/pop/POPAnimator.h create mode 120000 Example/Pods/Headers/Private/pop/POPAnimatorPrivate.h create mode 120000 Example/Pods/Headers/Private/pop/POPBasicAnimation.h create mode 120000 Example/Pods/Headers/Private/pop/POPBasicAnimationInternal.h create mode 120000 Example/Pods/Headers/Private/pop/POPCGUtils.h create mode 120000 Example/Pods/Headers/Private/pop/POPCustomAnimation.h create mode 120000 Example/Pods/Headers/Private/pop/POPDecayAnimation.h create mode 120000 Example/Pods/Headers/Private/pop/POPDecayAnimationInternal.h create mode 120000 Example/Pods/Headers/Private/pop/POPDefines.h create mode 120000 Example/Pods/Headers/Private/pop/POPGeometry.h create mode 120000 Example/Pods/Headers/Private/pop/POPLayerExtras.h create mode 120000 Example/Pods/Headers/Private/pop/POPMath.h create mode 120000 Example/Pods/Headers/Private/pop/POPPropertyAnimation.h create mode 120000 Example/Pods/Headers/Private/pop/POPPropertyAnimationInternal.h create mode 120000 Example/Pods/Headers/Private/pop/POPSpringAnimation.h create mode 120000 Example/Pods/Headers/Private/pop/POPSpringAnimationInternal.h create mode 120000 Example/Pods/Headers/Private/pop/POPSpringSolver.h create mode 120000 Example/Pods/Headers/Private/pop/POPVector.h create mode 120000 Example/Pods/Headers/Private/pop/TransformationMatrix.h create mode 120000 Example/Pods/Headers/Private/pop/UnitBezier.h create mode 120000 Example/Pods/Headers/Public/FBSnapshotTestCase/FBSnapshotTestCase.h create mode 120000 Example/Pods/Headers/Public/FBSnapshotTestCase/FBSnapshotTestCasePlatform.h create mode 120000 Example/Pods/Headers/Public/FBSnapshotTestCase/FBSnapshotTestController.h create mode 120000 Example/Pods/Headers/Public/FBSnapshotTestCase/UIImage+Compare.h create mode 120000 Example/Pods/Headers/Public/FBSnapshotTestCase/UIImage+Diff.h create mode 120000 Example/Pods/Headers/Public/PureLayout/ALView+PureLayout.h create mode 120000 Example/Pods/Headers/Public/PureLayout/NSArray+PureLayout.h create mode 120000 Example/Pods/Headers/Public/PureLayout/NSLayoutConstraint+PureLayout.h create mode 120000 Example/Pods/Headers/Public/PureLayout/PureLayout+Internal.h create mode 120000 Example/Pods/Headers/Public/PureLayout/PureLayout.h create mode 120000 Example/Pods/Headers/Public/PureLayout/PureLayoutDefines.h create mode 120000 Example/Pods/Headers/Public/TabBarPicker/TabBarItem.h create mode 120000 Example/Pods/Headers/Public/TabBarPicker/TabBarPicker.h create mode 120000 Example/Pods/Headers/Public/TabBarPicker/TabBarSubItem.h create mode 120000 Example/Pods/Headers/Public/pop/POP.h create mode 120000 Example/Pods/Headers/Public/pop/POPAnimatableProperty.h create mode 120000 Example/Pods/Headers/Public/pop/POPAnimation.h create mode 120000 Example/Pods/Headers/Public/pop/POPAnimationEvent.h create mode 120000 Example/Pods/Headers/Public/pop/POPAnimationExtras.h create mode 120000 Example/Pods/Headers/Public/pop/POPAnimationTracer.h create mode 120000 Example/Pods/Headers/Public/pop/POPAnimator.h create mode 120000 Example/Pods/Headers/Public/pop/POPBasicAnimation.h create mode 120000 Example/Pods/Headers/Public/pop/POPCustomAnimation.h create mode 120000 Example/Pods/Headers/Public/pop/POPDecayAnimation.h create mode 120000 Example/Pods/Headers/Public/pop/POPDefines.h create mode 120000 Example/Pods/Headers/Public/pop/POPGeometry.h create mode 120000 Example/Pods/Headers/Public/pop/POPLayerExtras.h create mode 120000 Example/Pods/Headers/Public/pop/POPPropertyAnimation.h create mode 120000 Example/Pods/Headers/Public/pop/POPSpringAnimation.h create mode 100644 Example/Pods/Local Podspecs/TabBarPicker.podspec.json create mode 100644 Example/Pods/Manifest.lock create mode 100644 Example/Pods/Pods.xcodeproj/project.pbxproj create mode 100644 Example/Pods/Pods.xcodeproj/xcshareddata/xcschemes/Pods-TabBarPicker_Example-TabBarPicker-TabBarPicker.xcscheme create mode 100644 Example/Pods/Pods.xcodeproj/xcshareddata/xcschemes/Pods-TabBarPicker_Example-TabBarPicker.xcscheme create mode 100644 Example/Pods/Pods.xcodeproj/xcshareddata/xcschemes/Pods-TabBarPicker_Tests-TabBarPicker-TabBarPicker.xcscheme create mode 100644 Example/Pods/Pods.xcodeproj/xcshareddata/xcschemes/Pods-TabBarPicker_Tests-TabBarPicker.xcscheme create mode 100755 Example/Pods/PureLayout/LICENSE create mode 100755 Example/Pods/PureLayout/PureLayout/PureLayout/ALView+PureLayout.h create mode 100755 Example/Pods/PureLayout/PureLayout/PureLayout/ALView+PureLayout.m create mode 100755 Example/Pods/PureLayout/PureLayout/PureLayout/NSArray+PureLayout.h create mode 100755 Example/Pods/PureLayout/PureLayout/PureLayout/NSArray+PureLayout.m create mode 100755 Example/Pods/PureLayout/PureLayout/PureLayout/NSLayoutConstraint+PureLayout.h create mode 100755 Example/Pods/PureLayout/PureLayout/PureLayout/NSLayoutConstraint+PureLayout.m create mode 100644 Example/Pods/PureLayout/PureLayout/PureLayout/PureLayout+Internal.h create mode 100755 Example/Pods/PureLayout/PureLayout/PureLayout/PureLayout.h create mode 100755 Example/Pods/PureLayout/PureLayout/PureLayout/PureLayoutDefines.h create mode 100644 Example/Pods/PureLayout/README.md create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Example-TabBarPicker/Info.plist create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Example-TabBarPicker/Pods-TabBarPicker_Example-TabBarPicker-Private.xcconfig create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Example-TabBarPicker/Pods-TabBarPicker_Example-TabBarPicker-dummy.m create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Example-TabBarPicker/Pods-TabBarPicker_Example-TabBarPicker-prefix.pch create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Example-TabBarPicker/Pods-TabBarPicker_Example-TabBarPicker-umbrella.h create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Example-TabBarPicker/Pods-TabBarPicker_Example-TabBarPicker.modulemap rename Pod/Classes/ReplaceMe.m => Example/Pods/Target Support Files/Pods-TabBarPicker_Example-TabBarPicker/Pods-TabBarPicker_Example-TabBarPicker.xcconfig (100%) create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Example/Info.plist create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Example/Pods-TabBarPicker_Example-acknowledgements.markdown create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Example/Pods-TabBarPicker_Example-acknowledgements.plist create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Example/Pods-TabBarPicker_Example-dummy.m create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Example/Pods-TabBarPicker_Example-environment.h create mode 100755 Example/Pods/Target Support Files/Pods-TabBarPicker_Example/Pods-TabBarPicker_Example-frameworks.sh create mode 100755 Example/Pods/Target Support Files/Pods-TabBarPicker_Example/Pods-TabBarPicker_Example-resources.sh create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Example/Pods-TabBarPicker_Example-umbrella.h create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Example/Pods-TabBarPicker_Example.debug.xcconfig create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Example/Pods-TabBarPicker_Example.modulemap create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Example/Pods-TabBarPicker_Example.release.xcconfig create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-FBSnapshotTestCase/Info.plist create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-FBSnapshotTestCase/Pods-TabBarPicker_Tests-FBSnapshotTestCase-Private.xcconfig create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-FBSnapshotTestCase/Pods-TabBarPicker_Tests-FBSnapshotTestCase-dummy.m create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-FBSnapshotTestCase/Pods-TabBarPicker_Tests-FBSnapshotTestCase-prefix.pch create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-FBSnapshotTestCase/Pods-TabBarPicker_Tests-FBSnapshotTestCase-umbrella.h create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-FBSnapshotTestCase/Pods-TabBarPicker_Tests-FBSnapshotTestCase.modulemap create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-FBSnapshotTestCase/Pods-TabBarPicker_Tests-FBSnapshotTestCase.xcconfig create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-PureLayout/Info.plist create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-PureLayout/Pods-TabBarPicker_Tests-PureLayout-Private.xcconfig create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-PureLayout/Pods-TabBarPicker_Tests-PureLayout-dummy.m create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-PureLayout/Pods-TabBarPicker_Tests-PureLayout-prefix.pch create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-PureLayout/Pods-TabBarPicker_Tests-PureLayout-umbrella.h create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-PureLayout/Pods-TabBarPicker_Tests-PureLayout.modulemap create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-PureLayout/Pods-TabBarPicker_Tests-PureLayout.xcconfig create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-TabBarPicker/Info.plist create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-TabBarPicker/Pods-TabBarPicker_Tests-TabBarPicker-Private.xcconfig create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-TabBarPicker/Pods-TabBarPicker_Tests-TabBarPicker-dummy.m create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-TabBarPicker/Pods-TabBarPicker_Tests-TabBarPicker-prefix.pch create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-TabBarPicker/Pods-TabBarPicker_Tests-TabBarPicker-umbrella.h create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-TabBarPicker/Pods-TabBarPicker_Tests-TabBarPicker.modulemap create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-TabBarPicker/Pods-TabBarPicker_Tests-TabBarPicker.xcconfig create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-pop/Info.plist create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-pop/Pods-TabBarPicker_Tests-pop-Private.xcconfig create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-pop/Pods-TabBarPicker_Tests-pop-dummy.m create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-pop/Pods-TabBarPicker_Tests-pop-prefix.pch create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-pop/Pods-TabBarPicker_Tests-pop-umbrella.h create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-pop/Pods-TabBarPicker_Tests-pop.modulemap create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-pop/Pods-TabBarPicker_Tests-pop.xcconfig create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Tests/Info.plist create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Tests/Pods-TabBarPicker_Tests-acknowledgements.markdown create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Tests/Pods-TabBarPicker_Tests-acknowledgements.plist create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Tests/Pods-TabBarPicker_Tests-dummy.m create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Tests/Pods-TabBarPicker_Tests-environment.h create mode 100755 Example/Pods/Target Support Files/Pods-TabBarPicker_Tests/Pods-TabBarPicker_Tests-frameworks.sh create mode 100755 Example/Pods/Target Support Files/Pods-TabBarPicker_Tests/Pods-TabBarPicker_Tests-resources.sh create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Tests/Pods-TabBarPicker_Tests-umbrella.h create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Tests/Pods-TabBarPicker_Tests.debug.xcconfig create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Tests/Pods-TabBarPicker_Tests.modulemap create mode 100644 Example/Pods/Target Support Files/Pods-TabBarPicker_Tests/Pods-TabBarPicker_Tests.release.xcconfig create mode 100644 Example/Pods/pop/LICENSE create mode 100644 Example/Pods/pop/README.md create mode 100644 Example/Pods/pop/pop/POP.h create mode 100644 Example/Pods/pop/pop/POPAction.h create mode 100644 Example/Pods/pop/pop/POPAnimatableProperty.h create mode 100644 Example/Pods/pop/pop/POPAnimatableProperty.mm create mode 100644 Example/Pods/pop/pop/POPAnimation.h create mode 100644 Example/Pods/pop/pop/POPAnimation.mm create mode 100644 Example/Pods/pop/pop/POPAnimationEvent.h create mode 100644 Example/Pods/pop/pop/POPAnimationEvent.mm create mode 100644 Example/Pods/pop/pop/POPAnimationEventInternal.h create mode 100644 Example/Pods/pop/pop/POPAnimationExtras.h create mode 100644 Example/Pods/pop/pop/POPAnimationExtras.mm create mode 100644 Example/Pods/pop/pop/POPAnimationInternal.h create mode 100644 Example/Pods/pop/pop/POPAnimationPrivate.h create mode 100644 Example/Pods/pop/pop/POPAnimationRuntime.h create mode 100644 Example/Pods/pop/pop/POPAnimationRuntime.mm create mode 100644 Example/Pods/pop/pop/POPAnimationTracer.h create mode 100644 Example/Pods/pop/pop/POPAnimationTracer.mm create mode 100644 Example/Pods/pop/pop/POPAnimationTracerInternal.h create mode 100644 Example/Pods/pop/pop/POPAnimator.h create mode 100644 Example/Pods/pop/pop/POPAnimator.mm create mode 100644 Example/Pods/pop/pop/POPAnimatorPrivate.h create mode 100644 Example/Pods/pop/pop/POPBasicAnimation.h create mode 100644 Example/Pods/pop/pop/POPBasicAnimation.mm create mode 100644 Example/Pods/pop/pop/POPBasicAnimationInternal.h create mode 100644 Example/Pods/pop/pop/POPCGUtils.h create mode 100644 Example/Pods/pop/pop/POPCGUtils.mm create mode 100644 Example/Pods/pop/pop/POPCustomAnimation.h create mode 100644 Example/Pods/pop/pop/POPCustomAnimation.mm create mode 100644 Example/Pods/pop/pop/POPDecayAnimation.h create mode 100644 Example/Pods/pop/pop/POPDecayAnimation.mm create mode 100644 Example/Pods/pop/pop/POPDecayAnimationInternal.h create mode 100644 Example/Pods/pop/pop/POPDefines.h create mode 100644 Example/Pods/pop/pop/POPGeometry.h create mode 100644 Example/Pods/pop/pop/POPGeometry.mm create mode 100644 Example/Pods/pop/pop/POPLayerExtras.h create mode 100644 Example/Pods/pop/pop/POPLayerExtras.mm create mode 100644 Example/Pods/pop/pop/POPMath.h create mode 100644 Example/Pods/pop/pop/POPMath.mm create mode 100644 Example/Pods/pop/pop/POPPropertyAnimation.h create mode 100644 Example/Pods/pop/pop/POPPropertyAnimation.mm create mode 100644 Example/Pods/pop/pop/POPPropertyAnimationInternal.h create mode 100644 Example/Pods/pop/pop/POPSpringAnimation.h create mode 100644 Example/Pods/pop/pop/POPSpringAnimation.mm create mode 100644 Example/Pods/pop/pop/POPSpringAnimationInternal.h create mode 100644 Example/Pods/pop/pop/POPSpringSolver.h create mode 100644 Example/Pods/pop/pop/POPVector.h create mode 100644 Example/Pods/pop/pop/POPVector.mm create mode 100644 Example/Pods/pop/pop/WebCore/FloatConversion.h create mode 100644 Example/Pods/pop/pop/WebCore/TransformationMatrix.cpp create mode 100644 Example/Pods/pop/pop/WebCore/TransformationMatrix.h create mode 100644 Example/Pods/pop/pop/WebCore/UnitBezier.h create mode 100644 Example/TabBarPicker.xcworkspace/contents.xcworkspacedata create mode 100644 Pod/Classes/TabBarItem.h create mode 100644 Pod/Classes/TabBarItem.m create mode 100644 Pod/Classes/TabBarPicker.h create mode 100644 Pod/Classes/TabBarPicker.m create mode 100644 Pod/Classes/TabBarSubItem.h create mode 100644 Pod/Classes/TabBarSubItem.m diff --git a/Example/Podfile b/Example/Podfile index 5377cf6..c55795d 100644 --- a/Example/Podfile +++ b/Example/Podfile @@ -9,4 +9,6 @@ target 'TabBarPicker_Tests', :exclusive => true do pod "TabBarPicker", :path => "../" pod 'FBSnapshotTestCase' + pod 'PureLayout' + pod 'pop', '~> 1.0' end diff --git a/Example/Podfile.lock b/Example/Podfile.lock new file mode 100644 index 0000000..dbf2dd0 --- /dev/null +++ b/Example/Podfile.lock @@ -0,0 +1,27 @@ +PODS: + - FBSnapshotTestCase (2.0.2): + - FBSnapshotTestCase/SwiftSupport (= 2.0.2) + - FBSnapshotTestCase/Core (2.0.2) + - FBSnapshotTestCase/SwiftSupport (2.0.2): + - FBSnapshotTestCase/Core + - pop (1.0.7) + - PureLayout (2.0.6) + - TabBarPicker (0.1.0) + +DEPENDENCIES: + - FBSnapshotTestCase + - pop (~> 1.0) + - PureLayout + - TabBarPicker (from `../`) + +EXTERNAL SOURCES: + TabBarPicker: + :path: ../ + +SPEC CHECKSUMS: + FBSnapshotTestCase: fd500d5b282c4ec60215d26d0b58b0cf271dd0d6 + pop: 628ffc631644601567ee8bfaaaea493ebd7d0923 + PureLayout: f25f0bb904d5ccfe6e31da3cb869185259f02e0d + TabBarPicker: f26d10a5d9f460b5a5a2d5ce5b48635c802577c5 + +COCOAPODS: 0.37.2 diff --git a/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestCase.h b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestCase.h new file mode 100644 index 0000000..12aa7d1 --- /dev/null +++ b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestCase.h @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2013, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +#import + +#import + +#import + +#import + +/** + Similar to our much-loved XCTAssert() macros. Use this to perform your test. No need to write an explanation, though. + @param view The view to snapshot + @param identifier An optional identifier, used if there are multiple snapshot tests in a given -test method. + @param suffixes An NSOrderedSet of strings for the different suffixes + @param tolerance The percentage of pixels that can differ and still count as an 'identical' view + */ +#define FBSnapshotVerifyViewWithOptions(view__, identifier__, suffixes__, tolerance__) \ +{ \ +NSString *envReferenceImageDirectory = [NSProcessInfo processInfo].environment[@"FB_REFERENCE_IMAGE_DIR"]; \ +NSError *error__ = nil; \ +BOOL comparisonSuccess__; \ +XCTAssertTrue((suffixes__.count > 0), @"Suffixes set cannot be empty %@", suffixes__); \ +XCTAssertNotNil(envReferenceImageDirectory, @"Missing value for referenceImagesDirectory - Set FB_REFERENCE_IMAGE_DIR as Environment variable in your scheme.");\ +for (NSString *suffix__ in suffixes__) { \ +NSString *referenceImagesDirectory__ = [NSString stringWithFormat:@"%@%@", envReferenceImageDirectory, suffix__]; \ +comparisonSuccess__ = [self compareSnapshotOfView:(view__) referenceImagesDirectory:referenceImagesDirectory__ identifier:(identifier__) tolerance:(tolerance__) error:&error__]; \ +if (comparisonSuccess__ || self.recordMode) break; \ +} \ +XCTAssertTrue(comparisonSuccess__, @"Snapshot comparison failed: %@", error__); \ +XCTAssertFalse(self.recordMode, @"Test ran in record mode. Reference image is now saved. Disable record mode to perform an actual snapshot comparison!"); \ +} + +#define FBSnapshotVerifyView(view__, identifier__) \ +{ \ +FBSnapshotVerifyViewWithOptions(view__, identifier__, FBSnapshotTestCaseDefaultSuffixes(), 0); \ +} + +/** + Similar to our much-loved XCTAssert() macros. Use this to perform your test. No need to write an explanation, though. + @param layer The layer to snapshot + @param identifier An optional identifier, used is there are multiple snapshot tests in a given -test method. + @param suffixes An NSOrderedSet of strings for the different suffixes + @param tolerance The percentage of pixels that can differ and still count as an 'identical' layer + */ +#define FBSnapshotVerifyLayerWithOptions(layer__, identifier__, suffixes__, tolerance__) \ +{ \ +NSString *envReferenceImageDirectory = [NSProcessInfo processInfo].environment[@"FB_REFERENCE_IMAGE_DIR"]; \ +NSError *error__ = nil; \ +BOOL comparisonSuccess__; \ +XCTAssertTrue((suffixes__.count > 0), @"Suffixes set cannot be empty %@", suffixes__); \ +XCTAssertNotNil(envReferenceImageDirectory, @"Missing value for referenceImagesDirectory - Set FB_REFERENCE_IMAGE_DIR as Environment variable in your scheme.");\ +for (NSString *suffix__ in suffixes__) { \ +NSString *referenceImagesDirectory__ = [NSString stringWithFormat:@"%@%@", envReferenceImageDirectory, suffix__]; \ +comparisonSuccess__ = [self compareSnapshotOfLayer:(layer__) referenceImagesDirectory:referenceImagesDirectory__ identifier:(identifier__) tolerance:(tolerance__) error:&error__]; \ +if (comparisonSuccess__ || self.recordMode) break; \ +} \ +XCTAssertTrue(comparisonSuccess__, @"Snapshot comparison failed: %@", error__); \ +XCTAssertFalse(self.recordMode, @"Test ran in record mode. Reference image is now saved. Disable record mode to perform an actual snapshot comparison!"); \ +} + +#define FBSnapshotVerifyLayer(layer__, identifier__) \ +{ \ +FBSnapshotVerifyLayerWithOptions(layer__, identifier__, FBSnapshotTestCaseDefaultSuffixes(), 0); \ +} + +/** + The base class of view snapshotting tests. If you have small UI component, it's often easier to configure it in a test + and compare an image of the view to a reference image that write lots of complex layout-code tests. + + In order to flip the tests in your subclass to record the reference images set @c recordMode to @c YES. + + For example: + @code + - (void)setUp + { + [super setUp]; + self.recordMode = YES; + } + @endcode + */ +@interface FBSnapshotTestCase : XCTestCase + +/** + When YES, the test macros will save reference images, rather than performing an actual test. + */ +@property (readwrite, nonatomic, assign) BOOL recordMode; + +/** + Performs the comparison or records a snapshot of the layer if recordMode is YES. + @param layer The Layer to snapshot + @param referenceImagesDirectory The directory in which reference images are stored. + @param identifier An optional identifier, used if there are multiple snapshot tests in a given -test method. + @param tolerance The percentage difference to still count as identical - 0 mean pixel perfect, 1 means I don't care + @param errorPtr An error to log in an XCTAssert() macro if the method fails (missing reference image, images differ, etc). + @returns YES if the comparison (or saving of the reference image) succeeded. + */ +- (BOOL)compareSnapshotOfLayer:(CALayer *)layer + referenceImagesDirectory:(NSString *)referenceImagesDirectory + identifier:(NSString *)identifier + tolerance:(CGFloat)tolerance + error:(NSError **)errorPtr; + +/** + Performs the comparison or records a snapshot of the view if recordMode is YES. + @param view The view to snapshot + @param referenceImagesDirectory The directory in which reference images are stored. + @param identifier An optional identifier, used if there are multiple snapshot tests in a given -test method. + @param tolerance The percentage difference to still count as identical - 0 mean pixel perfect, 1 means I don't care + @param errorPtr An error to log in an XCTAssert() macro if the method fails (missing reference image, images differ, etc). + @returns YES if the comparison (or saving of the reference image) succeeded. + */ +- (BOOL)compareSnapshotOfView:(UIView *)view + referenceImagesDirectory:(NSString *)referenceImagesDirectory + identifier:(NSString *)identifier + tolerance:(CGFloat)tolerance + error:(NSError **)errorPtr; + +@end diff --git a/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestCase.m b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestCase.m new file mode 100644 index 0000000..30279f1 --- /dev/null +++ b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestCase.m @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2013, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +#import "FBSnapshotTestCase.h" + +#import "FBSnapshotTestController.h" + +@implementation FBSnapshotTestCase +{ + FBSnapshotTestController *_snapshotController; +} + +- (void)setUp +{ + [super setUp]; + _snapshotController = [[FBSnapshotTestController alloc] initWithTestName:NSStringFromClass([self class])]; +} + +- (void)tearDown +{ + _snapshotController = nil; + [super tearDown]; +} + +- (BOOL)recordMode +{ + return _snapshotController.recordMode; +} + +- (void)setRecordMode:(BOOL)recordMode +{ + NSAssert1(_snapshotController, @"%s cannot be called before [super setUp]", __FUNCTION__); + _snapshotController.recordMode = recordMode; +} + +- (BOOL)compareSnapshotOfLayer:(CALayer *)layer + referenceImagesDirectory:(NSString *)referenceImagesDirectory + identifier:(NSString *)identifier + tolerance:(CGFloat)tolerance + error:(NSError **)errorPtr +{ + return [self _compareSnapshotOfViewOrLayer:layer + referenceImagesDirectory:referenceImagesDirectory + identifier:identifier + tolerance:tolerance + error:errorPtr]; +} + +- (BOOL)compareSnapshotOfView:(UIView *)view + referenceImagesDirectory:(NSString *)referenceImagesDirectory + identifier:(NSString *)identifier + tolerance:(CGFloat)tolerance + error:(NSError **)errorPtr +{ + return [self _compareSnapshotOfViewOrLayer:view + referenceImagesDirectory:referenceImagesDirectory + identifier:identifier + tolerance:tolerance + error:errorPtr]; +} + +#pragma mark - +#pragma mark Private API + +- (BOOL)_compareSnapshotOfViewOrLayer:(id)viewOrLayer + referenceImagesDirectory:(NSString *)referenceImagesDirectory + identifier:(NSString *)identifier + tolerance:(CGFloat)tolerance + error:(NSError **)errorPtr +{ + _snapshotController.referenceImagesDirectory = referenceImagesDirectory; + return [_snapshotController compareSnapshotOfViewOrLayer:viewOrLayer + selector:self.invocation.selector + identifier:identifier + tolerance:tolerance + error:errorPtr]; +} + +@end diff --git a/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestCasePlatform.h b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestCasePlatform.h new file mode 100644 index 0000000..99f6480 --- /dev/null +++ b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestCasePlatform.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +#import + +#ifdef __cplusplus +extern "C" { +#endif + +/** + Returns a Boolean value that indicates whether the snapshot test is running in 64Bit. + This method is a convenience for creating the suffixes set based on the architecture + that the test is running. + + @returns @c YES if the test is running in 64bit, otherwise @c NO. + */ +BOOL FBSnapshotTestCaseIs64Bit(void); + +/** + Returns a default set of strings that is used to append a suffix based on the architectures. + @warning Do not modify this function, you can create your own and use it with @c FBSnapshotVerifyViewWithOptions() + + @returns An @c NSOrderedSet object containing strings that are appended to the reference images directory. + */ +NSOrderedSet *FBSnapshotTestCaseDefaultSuffixes(void); + +#ifdef __cplusplus +} +#endif diff --git a/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestCasePlatform.m b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestCasePlatform.m new file mode 100644 index 0000000..95746c8 --- /dev/null +++ b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestCasePlatform.m @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2015, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +#import + +BOOL FBSnapshotTestCaseIs64Bit(void) +{ +#if __LP64__ + return YES; +#else + return NO; +#endif +} + +NSOrderedSet *FBSnapshotTestCaseDefaultSuffixes(void) +{ + NSMutableOrderedSet *suffixesSet = [[NSMutableOrderedSet alloc] init]; + [suffixesSet addObject:@"_32"]; + [suffixesSet addObject:@"_64"]; + if (FBSnapshotTestCaseIs64Bit()) { + return [suffixesSet reversedOrderedSet]; + } + return [suffixesSet copy]; +} diff --git a/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestController.h b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestController.h new file mode 100644 index 0000000..885c9fa --- /dev/null +++ b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestController.h @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2013, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +#import +#import + +typedef NS_ENUM(NSInteger, FBSnapshotTestControllerErrorCode) { + FBSnapshotTestControllerErrorCodeUnknown, + FBSnapshotTestControllerErrorCodeNeedsRecord, + FBSnapshotTestControllerErrorCodePNGCreationFailed, + FBSnapshotTestControllerErrorCodeImagesDifferentSizes, + FBSnapshotTestControllerErrorCodeImagesDifferent, +}; +/** + Errors returned by the methods of FBSnapshotTestController use this domain. + */ +extern NSString *const FBSnapshotTestControllerErrorDomain; + +/** + Errors returned by the methods of FBSnapshotTestController sometimes contain this key in the `userInfo` dictionary. + */ +extern NSString *const FBReferenceImageFilePathKey; + +/** + Provides the heavy-lifting for FBSnapshotTestCase. It loads and saves images, along with performing the actual pixel- + by-pixel comparison of images. + Instances are initialized with the test class, and directories to read and write to. + */ +@interface FBSnapshotTestController : NSObject + +/** + Record snapshots. + **/ +@property (readwrite, nonatomic, assign) BOOL recordMode; + +/** + @param testClass The subclass of FBSnapshotTestCase that is using this controller. + @returns An instance of FBSnapshotTestController. + */ +- (instancetype)initWithTestClass:(Class)testClass; + +/** + Designated initializer. + @param testName The name of the tests. + @returns An instance of FBSnapshotTestController. + */ +- (instancetype)initWithTestName:(NSString *)testName; + + +/** + Performs the comparison of the layer. + @param layer The Layer to snapshot. + @param selector The test method being run. + @param identifier An optional identifier, used is there are muliptle snapshot tests in a given -test method. + @param error An error to log in an XCTAssert() macro if the method fails (missing reference image, images differ, etc). + @returns YES if the comparison (or saving of the reference image) succeeded. + */ +- (BOOL)compareSnapshotOfLayer:(CALayer *)layer + selector:(SEL)selector + identifier:(NSString *)identifier + error:(NSError **)errorPtr; + +/** + Performs the comparison of the view. + @param view The view to snapshot. + @param selector The test method being run. + @param identifier An optional identifier, used is there are muliptle snapshot tests in a given -test method. + @param error An error to log in an XCTAssert() macro if the method fails (missing reference image, images differ, etc). + @returns YES if the comparison (or saving of the reference image) succeeded. + */ +- (BOOL)compareSnapshotOfView:(UIView *)view + selector:(SEL)selector + identifier:(NSString *)identifier + error:(NSError **)errorPtr; + +/** + Performs the comparison of a view or layer. + @param view The view or layer to snapshot. + @param selector The test method being run. + @param identifier An optional identifier, used is there are muliptle snapshot tests in a given -test method. + @param tolerance The percentage of pixels that can differ and still be considered 'identical' + @param error An error to log in an XCTAssert() macro if the method fails (missing reference image, images differ, etc). + @returns YES if the comparison (or saving of the reference image) succeeded. + */ +- (BOOL)compareSnapshotOfViewOrLayer:(id)viewOrLayer + selector:(SEL)selector + identifier:(NSString *)identifier + tolerance:(CGFloat)tolerance + error:(NSError **)errorPtr; + + +/** + The directory in which referfence images are stored. + */ +@property (readwrite, nonatomic, copy) NSString *referenceImagesDirectory; + +/** + Loads a reference image. + @param selector The test method being run. + @param identifier The optional identifier, used when multiple images are tested in a single -test method. + @param errorPtr An error, if this methods returns nil, the error will be something useful. + @returns An image. + */ +- (UIImage *)referenceImageForSelector:(SEL)selector + identifier:(NSString *)identifier + error:(NSError **)errorPtr; + +/** + Saves a reference image. + @param selector The test method being run. + @param identifier The optional identifier, used when multiple images are tested in a single -test method. + @param errorPtr An error, if this methods returns NO, the error will be something useful. + @returns An image. + */ +- (BOOL)saveReferenceImage:(UIImage *)image + selector:(SEL)selector + identifier:(NSString *)identifier + error:(NSError **)errorPtr; + +/** + Performs a pixel-by-pixel comparison of the two images with an allowable margin of error. + @param referenceImage The reference (correct) image. + @param image The image to test against the reference. + @param tolerance The percentage of pixels that can differ and still be considered 'identical' + @param errorPtr An error that indicates why the comparison failed if it does. + @returns YES if the comparison succeeded and the images are the same(ish). + */ +- (BOOL)compareReferenceImage:(UIImage *)referenceImage + toImage:(UIImage *)image + tolerance:(CGFloat)tolerance + error:(NSError **)errorPtr; + +/** + Saves the reference image and the test image to `failedOutputDirectory`. + @param referenceImage The reference (correct) image. + @param testImage The image to test against the reference. + @param selector The test method being run. + @param identifier The optional identifier, used when multiple images are tested in a single -test method. + @param errorPtr An error that indicates why the comparison failed if it does. + @returns YES if the save succeeded. + */ +- (BOOL)saveFailedReferenceImage:(UIImage *)referenceImage + testImage:(UIImage *)testImage + selector:(SEL)selector + identifier:(NSString *)identifier + error:(NSError **)errorPtr; +@end diff --git a/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestController.m b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestController.m new file mode 100644 index 0000000..2a63f5a --- /dev/null +++ b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestController.m @@ -0,0 +1,384 @@ +/* + * Copyright (c) 2013, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +#import "FBSnapshotTestController.h" + +#import "UIImage+Compare.h" +#import "UIImage+Diff.h" + +#import + +NSString *const FBSnapshotTestControllerErrorDomain = @"FBSnapshotTestControllerErrorDomain"; + +NSString *const FBReferenceImageFilePathKey = @"FBReferenceImageFilePathKey"; + +@implementation FBSnapshotTestController +{ + NSString *_testName; + NSFileManager *_fileManager; +} + +#pragma mark - +#pragma mark Lifecycle + +- (instancetype)initWithTestClass:(Class)testClass; +{ + return [self initWithTestName:NSStringFromClass(testClass)]; +} + +- (instancetype)initWithTestName:(NSString *)testName +{ + if ((self = [super init])) { + _testName = [testName copy]; + _fileManager = [[NSFileManager alloc] init]; + } + return self; +} + +#pragma mark - +#pragma mark Properties + +- (NSString *)description +{ + return [NSString stringWithFormat:@"%@ %@", [super description], _referenceImagesDirectory]; +} + +#pragma mark - +#pragma mark Public API + +- (UIImage *)referenceImageForSelector:(SEL)selector + identifier:(NSString *)identifier + error:(NSError **)errorPtr +{ + NSString *filePath = [self _referenceFilePathForSelector:selector identifier:identifier]; + UIImage *image = [UIImage imageWithContentsOfFile:filePath]; + if (nil == image && NULL != errorPtr) { + BOOL exists = [_fileManager fileExistsAtPath:filePath]; + if (!exists) { + *errorPtr = [NSError errorWithDomain:FBSnapshotTestControllerErrorDomain + code:FBSnapshotTestControllerErrorCodeNeedsRecord + userInfo:@{ + FBReferenceImageFilePathKey: filePath, + NSLocalizedDescriptionKey: @"Unable to load reference image.", + NSLocalizedFailureReasonErrorKey: @"Reference image not found. You need to run the test in record mode", + }]; + } else { + *errorPtr = [NSError errorWithDomain:FBSnapshotTestControllerErrorDomain + code:FBSnapshotTestControllerErrorCodeUnknown + userInfo:nil]; + } + } + return image; +} + +- (BOOL)saveReferenceImage:(UIImage *)image + selector:(SEL)selector + identifier:(NSString *)identifier + error:(NSError **)errorPtr +{ + BOOL didWrite = NO; + if (nil != image) { + NSString *filePath = [self _referenceFilePathForSelector:selector identifier:identifier]; + NSData *pngData = UIImagePNGRepresentation(image); + if (nil != pngData) { + NSError *creationError = nil; + BOOL didCreateDir = [_fileManager createDirectoryAtPath:[filePath stringByDeletingLastPathComponent] + withIntermediateDirectories:YES + attributes:nil + error:&creationError]; + if (!didCreateDir) { + if (NULL != errorPtr) { + *errorPtr = creationError; + } + return NO; + } + didWrite = [pngData writeToFile:filePath options:NSDataWritingAtomic error:errorPtr]; + if (didWrite) { + NSLog(@"Reference image save at: %@", filePath); + } + } else { + if (nil != errorPtr) { + *errorPtr = [NSError errorWithDomain:FBSnapshotTestControllerErrorDomain + code:FBSnapshotTestControllerErrorCodePNGCreationFailed + userInfo:@{ + FBReferenceImageFilePathKey: filePath, + }]; + } + } + } + return didWrite; +} + +- (BOOL)saveFailedReferenceImage:(UIImage *)referenceImage + testImage:(UIImage *)testImage + selector:(SEL)selector + identifier:(NSString *)identifier + error:(NSError **)errorPtr +{ + NSData *referencePNGData = UIImagePNGRepresentation(referenceImage); + NSData *testPNGData = UIImagePNGRepresentation(testImage); + + NSString *referencePath = [self _failedFilePathForSelector:selector + identifier:identifier + fileNameType:FBTestSnapshotFileNameTypeFailedReference]; + + NSError *creationError = nil; + BOOL didCreateDir = [_fileManager createDirectoryAtPath:[referencePath stringByDeletingLastPathComponent] + withIntermediateDirectories:YES + attributes:nil + error:&creationError]; + if (!didCreateDir) { + if (NULL != errorPtr) { + *errorPtr = creationError; + } + return NO; + } + + if (![referencePNGData writeToFile:referencePath options:NSDataWritingAtomic error:errorPtr]) { + return NO; + } + + NSString *testPath = [self _failedFilePathForSelector:selector + identifier:identifier + fileNameType:FBTestSnapshotFileNameTypeFailedTest]; + + if (![testPNGData writeToFile:testPath options:NSDataWritingAtomic error:errorPtr]) { + return NO; + } + + NSString *diffPath = [self _failedFilePathForSelector:selector + identifier:identifier + fileNameType:FBTestSnapshotFileNameTypeFailedTestDiff]; + + UIImage *diffImage = [referenceImage diffWithImage:testImage]; + NSData *diffImageData = UIImagePNGRepresentation(diffImage); + + if (![diffImageData writeToFile:diffPath options:NSDataWritingAtomic error:errorPtr]) { + return NO; + } + + NSLog(@"If you have Kaleidoscope installed you can run this command to see an image diff:\n" + @"ksdiff \"%@\" \"%@\"", referencePath, testPath); + + return YES; +} + +- (BOOL)compareReferenceImage:(UIImage *)referenceImage + toImage:(UIImage *)image + tolerance:(CGFloat)tolerance + error:(NSError **)errorPtr { + if (CGSizeEqualToSize(referenceImage.size, image.size)) { + + BOOL imagesEqual = [referenceImage compareWithImage:image tolerance:tolerance]; + if (NULL != errorPtr) { + *errorPtr = [NSError errorWithDomain:FBSnapshotTestControllerErrorDomain + code:FBSnapshotTestControllerErrorCodeImagesDifferent + userInfo:@{ + NSLocalizedDescriptionKey: @"Images different", + }]; + } + return imagesEqual; + } + if (NULL != errorPtr) { + *errorPtr = [NSError errorWithDomain:FBSnapshotTestControllerErrorDomain + code:FBSnapshotTestControllerErrorCodeImagesDifferentSizes + userInfo:@{ + NSLocalizedDescriptionKey: @"Images different sizes", + NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:@"referenceImage:%@, image:%@", + NSStringFromCGSize(referenceImage.size), + NSStringFromCGSize(image.size)], + }]; + } + return NO; +} + +#pragma mark - +#pragma mark Private API + +typedef NS_ENUM(NSUInteger, FBTestSnapshotFileNameType) { + FBTestSnapshotFileNameTypeReference, + FBTestSnapshotFileNameTypeFailedReference, + FBTestSnapshotFileNameTypeFailedTest, + FBTestSnapshotFileNameTypeFailedTestDiff, +}; + +- (NSString *)_fileNameForSelector:(SEL)selector + identifier:(NSString *)identifier + fileNameType:(FBTestSnapshotFileNameType)fileNameType +{ + NSString *fileName = nil; + switch (fileNameType) { + case FBTestSnapshotFileNameTypeFailedReference: + fileName = @"reference_"; + break; + case FBTestSnapshotFileNameTypeFailedTest: + fileName = @"failed_"; + break; + case FBTestSnapshotFileNameTypeFailedTestDiff: + fileName = @"diff_"; + break; + default: + fileName = @""; + break; + } + fileName = [fileName stringByAppendingString:NSStringFromSelector(selector)]; + if (0 < identifier.length) { + fileName = [fileName stringByAppendingFormat:@"_%@", identifier]; + } + if ([[UIScreen mainScreen] scale] > 1) { + fileName = [fileName stringByAppendingFormat:@"@%.fx", [[UIScreen mainScreen] scale]]; + } + fileName = [fileName stringByAppendingPathExtension:@"png"]; + return fileName; +} + +- (NSString *)_referenceFilePathForSelector:(SEL)selector identifier:(NSString *)identifier +{ + NSString *fileName = [self _fileNameForSelector:selector + identifier:identifier + fileNameType:FBTestSnapshotFileNameTypeReference]; + NSString *filePath = [_referenceImagesDirectory stringByAppendingPathComponent:_testName]; + filePath = [filePath stringByAppendingPathComponent:fileName]; + return filePath; +} + +- (NSString *)_failedFilePathForSelector:(SEL)selector + identifier:(NSString *)identifier + fileNameType:(FBTestSnapshotFileNameType)fileNameType +{ + NSString *fileName = [self _fileNameForSelector:selector + identifier:identifier + fileNameType:fileNameType]; + NSString *folderPath = NSTemporaryDirectory(); + if (getenv("IMAGE_DIFF_DIR")) { + folderPath = @(getenv("IMAGE_DIFF_DIR")); + } + NSString *filePath = [folderPath stringByAppendingPathComponent:_testName]; + filePath = [filePath stringByAppendingPathComponent:fileName]; + return filePath; +} + +- (BOOL)compareSnapshotOfLayer:(CALayer *)layer + selector:(SEL)selector + identifier:(NSString *)identifier + error:(NSError **)errorPtr +{ + return [self compareSnapshotOfViewOrLayer:layer + selector:selector + identifier:identifier + tolerance:0 + error:errorPtr]; +} + +- (BOOL)compareSnapshotOfView:(UIView *)view + selector:(SEL)selector + identifier:(NSString *)identifier + error:(NSError **)errorPtr +{ + return [self compareSnapshotOfViewOrLayer:view + selector:selector + identifier:identifier + tolerance:0 + error:errorPtr]; +} + +- (BOOL)compareSnapshotOfViewOrLayer:(id)viewOrLayer + selector:(SEL)selector + identifier:(NSString *)identifier + tolerance:(CGFloat)tolerance + error:(NSError **)errorPtr +{ + if (self.recordMode) { + return [self _recordSnapshotOfViewOrLayer:viewOrLayer selector:selector identifier:identifier error:errorPtr]; + } else { + return [self _performPixelComparisonWithViewOrLayer:viewOrLayer selector:selector identifier:identifier tolerance:tolerance error:errorPtr]; + } +} + +#pragma mark - +#pragma mark Private API + +- (BOOL)_performPixelComparisonWithViewOrLayer:(id)viewOrLayer + selector:(SEL)selector + identifier:(NSString *)identifier + tolerance:(CGFloat)tolerance + error:(NSError **)errorPtr +{ + UIImage *referenceImage = [self referenceImageForSelector:selector identifier:identifier error:errorPtr]; + if (nil != referenceImage) { + UIImage *snapshot = [self _snapshotViewOrLayer:viewOrLayer]; + BOOL imagesSame = [self compareReferenceImage:referenceImage toImage:snapshot tolerance:tolerance error:errorPtr]; + if (!imagesSame) { + [self saveFailedReferenceImage:referenceImage + testImage:snapshot + selector:selector + identifier:identifier + error:errorPtr]; + } + return imagesSame; + } + return NO; +} + +- (BOOL)_recordSnapshotOfViewOrLayer:(id)viewOrLayer + selector:(SEL)selector + identifier:(NSString *)identifier + error:(NSError **)errorPtr +{ + UIImage *snapshot = [self _snapshotViewOrLayer:viewOrLayer]; + return [self saveReferenceImage:snapshot selector:selector identifier:identifier error:errorPtr]; +} + +- (UIImage *)_snapshotViewOrLayer:(id)viewOrLayer +{ + CALayer *layer = nil; + + if ([viewOrLayer isKindOfClass:[UIView class]]) { + return [self _renderView:viewOrLayer]; + } else if ([viewOrLayer isKindOfClass:[CALayer class]]) { + layer = (CALayer *)viewOrLayer; + [layer layoutIfNeeded]; + return [self _renderLayer:layer]; + } else { + [NSException raise:@"Only UIView and CALayer classes can be snapshotted" format:@"%@", viewOrLayer]; + } + return nil; +} + +- (UIImage *)_renderLayer:(CALayer *)layer +{ + CGRect bounds = layer.bounds; + + NSAssert1(CGRectGetWidth(bounds), @"Zero width for layer %@", layer); + NSAssert1(CGRectGetHeight(bounds), @"Zero height for layer %@", layer); + + UIGraphicsBeginImageContextWithOptions(bounds.size, NO, 0); + CGContextRef context = UIGraphicsGetCurrentContext(); + NSAssert1(context, @"Could not generate context for layer %@", layer); + + CGContextSaveGState(context); + { + [layer renderInContext:context]; + } + CGContextRestoreGState(context); + + UIImage *snapshot = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + + return snapshot; +} + +- (UIImage *)_renderView:(UIView *)view +{ + [view layoutIfNeeded]; + return [self _renderLayer:view.layer]; +} + +@end diff --git a/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/SwiftSupport.swift b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/SwiftSupport.swift new file mode 100644 index 0000000..e1b2a4f --- /dev/null +++ b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/SwiftSupport.swift @@ -0,0 +1,58 @@ +/* +* Copyright (c) 2015, Facebook, Inc. +* All rights reserved. +* +* This source code is licensed under the BSD-style license found in the +* LICENSE file in the root directory of this source tree. An additional grant +* of patent rights can be found in the PATENTS file in the same directory. +* +*/ + +public extension FBSnapshotTestCase { + public func FBSnapshotVerifyView(view: UIView, identifier: String = "", suffixes: NSOrderedSet = FBSnapshotTestCaseDefaultSuffixes(), file: String = __FILE__, line: UInt = __LINE__) { + let envReferenceImageDirectory = NSProcessInfo.processInfo().environment["FB_REFERENCE_IMAGE_DIR"] as? String + var error: NSError? + + if let envReferenceImageDirectory = envReferenceImageDirectory { + for suffix in suffixes { + let referenceImagesDirectory = "\(envReferenceImageDirectory)\(suffix)" + let comparisonSuccess = compareSnapshotOfView(view, referenceImagesDirectory: referenceImagesDirectory, identifier: identifier, tolerance: 0, error: &error) + if comparisonSuccess || recordMode { + break + } + + assert(comparisonSuccess, message: "Snapshot comparison failed: \(error)", file: file, line: line) + assert(recordMode == false, message: "Test ran in record mode. Reference image is now saved. Disable record mode to perform an actual snapshot comparison!", file: file, line: line) + } + } else { + assert(false, message: "Missing value for referenceImagesDirectory - Set FB_REFERENCE_IMAGE_DIR as Environment variable in your scheme.", file: file, line: line) + } + } + + public func FBSnapshotVerifyLayer(layer: CALayer, identifier: String = "", suffixes: NSOrderedSet = FBSnapshotTestCaseDefaultSuffixes(), file: String = __FILE__, line: UInt = __LINE__) { + let envReferenceImageDirectory = NSProcessInfo.processInfo().environment["FB_REFERENCE_IMAGE_DIR"] as? String + var error: NSError? + var comparisonSuccess = false + + if let envReferenceImageDirectory = envReferenceImageDirectory { + for suffix in suffixes { + let referenceImagesDirectory = "\(envReferenceImageDirectory)\(suffix)" + comparisonSuccess = compareSnapshotOfLayer(layer, referenceImagesDirectory: referenceImagesDirectory, identifier: identifier, tolerance: 0, error: &error) + if comparisonSuccess || recordMode { + break + } + + assert(comparisonSuccess, message: "Snapshot comparison failed: \(error)", file: file, line: line) + assert(recordMode == false, message: "Test ran in record mode. Reference image is now saved. Disable record mode to perform an actual snapshot comparison!", file: file, line: line) + } + } else { + XCTFail("Missing value for referenceImagesDirectory - Set FB_REFERENCE_IMAGE_DIR as Environment variable in your scheme.") + } + } + + func assert(assertion: Bool, message: String, file: String, line: UInt) { + if !assertion { + XCTFail(message, file: file, line: line) + } + } +} diff --git a/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/UIImage+Compare.h b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/UIImage+Compare.h new file mode 100644 index 0000000..b6f9c31 --- /dev/null +++ b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/UIImage+Compare.h @@ -0,0 +1,37 @@ +// +// Created by Gabriel Handford on 3/1/09. +// Copyright 2009-2013. All rights reserved. +// Created by John Boiles on 10/20/11. +// Copyright (c) 2011. All rights reserved +// Modified by Felix Schulze on 2/11/13. +// Copyright 2013. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +#import + +@interface UIImage (Compare) + +- (BOOL)compareWithImage:(UIImage *)image tolerance:(CGFloat)tolerance; + +@end diff --git a/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/UIImage+Compare.m b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/UIImage+Compare.m new file mode 100644 index 0000000..ac5bb94 --- /dev/null +++ b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/UIImage+Compare.m @@ -0,0 +1,134 @@ +// +// Created by Gabriel Handford on 3/1/09. +// Copyright 2009-2013. All rights reserved. +// Created by John Boiles on 10/20/11. +// Copyright (c) 2011. All rights reserved +// Modified by Felix Schulze on 2/11/13. +// Copyright 2013. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +#import "UIImage+Compare.h" + +// This makes debugging much more fun +typedef union { + uint32_t raw; + unsigned char bytes[4]; + struct { + char red; + char green; + char blue; + char alpha; + } __attribute__ ((packed)) pixels; +} FBComparePixel; + +@implementation UIImage (Compare) + +- (BOOL)compareWithImage:(UIImage *)image tolerance:(CGFloat)tolerance +{ + NSAssert(CGSizeEqualToSize(self.size, image.size), @"Images must be same size."); + + CGSize referenceImageSize = CGSizeMake(CGImageGetWidth(self.CGImage), CGImageGetHeight(self.CGImage)); + CGSize imageSize = CGSizeMake(CGImageGetWidth(image.CGImage), CGImageGetHeight(image.CGImage)); + + // The images have the equal size, so we could use the smallest amount of bytes because of byte padding + size_t minBytesPerRow = MIN(CGImageGetBytesPerRow(self.CGImage), CGImageGetBytesPerRow(image.CGImage)); + size_t referenceImageSizeBytes = referenceImageSize.height * minBytesPerRow; + void *referenceImagePixels = calloc(1, referenceImageSizeBytes); + void *imagePixels = calloc(1, referenceImageSizeBytes); + + if (!referenceImagePixels || !imagePixels) { + free(referenceImagePixels); + free(imagePixels); + return NO; + } + + CGContextRef referenceImageContext = CGBitmapContextCreate(referenceImagePixels, + referenceImageSize.width, + referenceImageSize.height, + CGImageGetBitsPerComponent(self.CGImage), + minBytesPerRow, + CGImageGetColorSpace(self.CGImage), + (CGBitmapInfo)kCGImageAlphaPremultipliedLast + ); + CGContextRef imageContext = CGBitmapContextCreate(imagePixels, + imageSize.width, + imageSize.height, + CGImageGetBitsPerComponent(image.CGImage), + minBytesPerRow, + CGImageGetColorSpace(image.CGImage), + (CGBitmapInfo)kCGImageAlphaPremultipliedLast + ); + + if (!referenceImageContext || !imageContext) { + CGContextRelease(referenceImageContext); + CGContextRelease(imageContext); + free(referenceImagePixels); + free(imagePixels); + return NO; + } + + CGContextDrawImage(referenceImageContext, CGRectMake(0, 0, referenceImageSize.width, referenceImageSize.height), self.CGImage); + CGContextDrawImage(imageContext, CGRectMake(0, 0, imageSize.width, imageSize.height), image.CGImage); + + CGContextRelease(referenceImageContext); + CGContextRelease(imageContext); + + BOOL imageEqual = YES; + + // Do a fast compare if we can + if (tolerance == 0) { + imageEqual = (memcmp(referenceImagePixels, imagePixels, referenceImageSizeBytes) == 0); + } else { + // Go through each pixel in turn and see if it is different + const NSInteger pixelCount = self.size.width * self.size.height; + + FBComparePixel *p1 = referenceImagePixels; + FBComparePixel *p2 = imagePixels; + + NSInteger numDiffPixels = 0; + for (int n = 0; n < pixelCount; ++n) { + // If this pixel is different, increment the pixel diff count and see + // if we have hit our limit. + if (p1->raw != p2->raw) { + numDiffPixels ++; + + CGFloat percent = (CGFloat)numDiffPixels / pixelCount; + if (percent > tolerance) { + imageEqual = NO; + break; + } + } + + p1++; + p2++; + } + } + + free(referenceImagePixels); + free(imagePixels); + + return imageEqual; +} + +@end diff --git a/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/UIImage+Diff.h b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/UIImage+Diff.h new file mode 100644 index 0000000..3559584 --- /dev/null +++ b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/UIImage+Diff.h @@ -0,0 +1,37 @@ +// +// Created by Gabriel Handford on 3/1/09. +// Copyright 2009-2013. All rights reserved. +// Created by John Boiles on 10/20/11. +// Copyright (c) 2011. All rights reserved +// Modified by Felix Schulze on 2/11/13. +// Copyright 2013. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +#import + +@interface UIImage (Diff) + +- (UIImage *)diffWithImage:(UIImage *)image; + +@end diff --git a/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/UIImage+Diff.m b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/UIImage+Diff.m new file mode 100644 index 0000000..cb3dae5 --- /dev/null +++ b/Example/Pods/FBSnapshotTestCase/FBSnapshotTestCase/UIImage+Diff.m @@ -0,0 +1,56 @@ +// +// Created by Gabriel Handford on 3/1/09. +// Copyright 2009-2013. All rights reserved. +// Created by John Boiles on 10/20/11. +// Copyright (c) 2011. All rights reserved +// Modified by Felix Schulze on 2/11/13. +// Copyright 2013. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +#import "UIImage+Diff.h" + +@implementation UIImage (Diff) + +- (UIImage *)diffWithImage:(UIImage *)image +{ + if (!image) { + return nil; + } + CGSize imageSize = CGSizeMake(MAX(self.size.width, image.size.width), MAX(self.size.height, image.size.height)); + UIGraphicsBeginImageContextWithOptions(imageSize, YES, 0); + CGContextRef context = UIGraphicsGetCurrentContext(); + [self drawInRect:CGRectMake(0, 0, self.size.width, self.size.height)]; + CGContextSetAlpha(context, 0.5); + CGContextBeginTransparencyLayer(context, NULL); + [image drawInRect:CGRectMake(0, 0, image.size.width, image.size.height)]; + CGContextSetBlendMode(context, kCGBlendModeDifference); + CGContextSetFillColorWithColor(context,[UIColor whiteColor].CGColor); + CGContextFillRect(context, CGRectMake(0, 0, self.size.width, self.size.height)); + CGContextEndTransparencyLayer(context); + UIImage *returnImage = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + return returnImage; +} + +@end diff --git a/Example/Pods/FBSnapshotTestCase/LICENSE b/Example/Pods/FBSnapshotTestCase/LICENSE new file mode 100644 index 0000000..2dd780c --- /dev/null +++ b/Example/Pods/FBSnapshotTestCase/LICENSE @@ -0,0 +1,29 @@ +BSD License + +For the FBSnapshotTestCase software + +Copyright (c) 2013, Facebook, Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name Facebook nor the names of its contributors may be used to + endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Example/Pods/FBSnapshotTestCase/README.md b/Example/Pods/FBSnapshotTestCase/README.md new file mode 100644 index 0000000..d9f638a --- /dev/null +++ b/Example/Pods/FBSnapshotTestCase/README.md @@ -0,0 +1,97 @@ +FBSnapshotTestCase +====================== + +[![Build Status](https://travis-ci.org/facebook/ios-snapshot-test-case.svg)](https://travis-ci.org/facebook/ios-snapshot-test-case) [![Cocoa Pod Version](https://cocoapod-badges.herokuapp.com/v/FBSnapshotTestCase/badge.svg)](http://cocoadocs.org/docsets/FBSnapshotTestCase/) + +What it does +------------ + +A "snapshot test case" takes a configured `UIView` or `CALayer` and uses the +`renderInContext:` method to get an image snapshot of its contents. It +compares this snapshot to a "reference image" stored in your source code +repository and fails the test if the two images don't match. + +Why? +---- + +At Facebook we write a lot of UI code. As you might imagine, each type of +feed story is rendered using a subclass of `UIView`. There are a lot of edge +cases that we want to handle correctly: + +- What if there is more text than can fit in the space available? +- What if an image doesn't match the size of an image view? +- What should the highlighted state look like? + +It's straightforward to test logic code, but less obvious how you should test +views. You can do a lot of rectangle asserts, but these are hard to understand +or visualize. Looking at an image diff shows you exactly what changed and how +it will look to users. + +We developed `FBSnapshotTestCase` to make snapshot tests easy. + +Installation with CocoaPods +--------------------------- + +1. Add the following lines to your Podfile: + + ``` + target "Tests" do + pod 'FBSnapshotTestCase' + end + ``` + + If you support iOS 7 use `FBSnapshotTestCase/Core` instead, which doesn't contain Swift support. + + Replace "Tests" with the name of your test project. + +2. Define `FB_REFERENCE_IMAGE_DIR` in your scheme. This should + point to the directory where you want reference images to be stored. At Facebook, + we normally use this: + +|Name|Value| +|:---|:----| +|`FB_REFERENCE_IMAGE_DIR`|`$(SOURCE_ROOT)/$(PROJECT_NAME)Tests/ReferenceImages`| + + +![](FBSnapshotTestCaseDemo/Scheme_FB_REFERENCE_IMAGE_DIR.png) + +Creating a snapshot test +------------------------ + +1. Subclass `FBSnapshotTestCase` instead of `XCTestCase`. +2. From within your test, use `FBSnapshotVerifyView`. +3. Run the test once with `self.recordMode = YES;` in the test's `-setUp` + method. (This creates the reference images on disk.) +4. Remove the line enabling record mode and run the test. + +Features +-------- + +- Automatically names reference images on disk according to test class and + selector. +- Prints a descriptive error message to the console on failure. (Bonus: + failure message includes a one-line command to see an image diff if + you have [Kaleidoscope](http://www.kaleidoscopeapp.com) installed.) +- Supply an optional "identifier" if you want to perform multiple snapshots + in a single test method. +- Support for `CALayer` via `FBSnapshotVerifyLayer`. + +Notes +----- + +Your unit test must be an "application test", not a "logic test." (That is, it +must be run within the Simulator so that it has access to UIKit.) In Xcode 5 +and later new projects only offer application tests, but older projects will +have separate targets for the two types. + +Authors +------- + +`FBSnapshotTestCase` was written at Facebook by +[Jonathan Dann](https://facebook.com/j.p.dann) with significant contributions by +[Todd Krabach](https://facebook.com/toddkrabach). + +License +------- + +`FBSnapshotTestCase` is BSD-licensed. See `LICENSE`. diff --git a/Example/Pods/Headers/Private/FBSnapshotTestCase/FBSnapshotTestCase.h b/Example/Pods/Headers/Private/FBSnapshotTestCase/FBSnapshotTestCase.h new file mode 120000 index 0000000..2925eab --- /dev/null +++ b/Example/Pods/Headers/Private/FBSnapshotTestCase/FBSnapshotTestCase.h @@ -0,0 +1 @@ +../../../FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestCase.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/FBSnapshotTestCase/FBSnapshotTestCasePlatform.h b/Example/Pods/Headers/Private/FBSnapshotTestCase/FBSnapshotTestCasePlatform.h new file mode 120000 index 0000000..6127a30 --- /dev/null +++ b/Example/Pods/Headers/Private/FBSnapshotTestCase/FBSnapshotTestCasePlatform.h @@ -0,0 +1 @@ +../../../FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestCasePlatform.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/FBSnapshotTestCase/FBSnapshotTestController.h b/Example/Pods/Headers/Private/FBSnapshotTestCase/FBSnapshotTestController.h new file mode 120000 index 0000000..4a7dea1 --- /dev/null +++ b/Example/Pods/Headers/Private/FBSnapshotTestCase/FBSnapshotTestController.h @@ -0,0 +1 @@ +../../../FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestController.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/FBSnapshotTestCase/UIImage+Compare.h b/Example/Pods/Headers/Private/FBSnapshotTestCase/UIImage+Compare.h new file mode 120000 index 0000000..a68eafb --- /dev/null +++ b/Example/Pods/Headers/Private/FBSnapshotTestCase/UIImage+Compare.h @@ -0,0 +1 @@ +../../../FBSnapshotTestCase/FBSnapshotTestCase/UIImage+Compare.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/FBSnapshotTestCase/UIImage+Diff.h b/Example/Pods/Headers/Private/FBSnapshotTestCase/UIImage+Diff.h new file mode 120000 index 0000000..f21e64d --- /dev/null +++ b/Example/Pods/Headers/Private/FBSnapshotTestCase/UIImage+Diff.h @@ -0,0 +1 @@ +../../../FBSnapshotTestCase/FBSnapshotTestCase/UIImage+Diff.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/PureLayout/ALView+PureLayout.h b/Example/Pods/Headers/Private/PureLayout/ALView+PureLayout.h new file mode 120000 index 0000000..ac489e2 --- /dev/null +++ b/Example/Pods/Headers/Private/PureLayout/ALView+PureLayout.h @@ -0,0 +1 @@ +../../../PureLayout/PureLayout/PureLayout/ALView+PureLayout.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/PureLayout/NSArray+PureLayout.h b/Example/Pods/Headers/Private/PureLayout/NSArray+PureLayout.h new file mode 120000 index 0000000..76395e6 --- /dev/null +++ b/Example/Pods/Headers/Private/PureLayout/NSArray+PureLayout.h @@ -0,0 +1 @@ +../../../PureLayout/PureLayout/PureLayout/NSArray+PureLayout.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/PureLayout/NSLayoutConstraint+PureLayout.h b/Example/Pods/Headers/Private/PureLayout/NSLayoutConstraint+PureLayout.h new file mode 120000 index 0000000..a2afdda --- /dev/null +++ b/Example/Pods/Headers/Private/PureLayout/NSLayoutConstraint+PureLayout.h @@ -0,0 +1 @@ +../../../PureLayout/PureLayout/PureLayout/NSLayoutConstraint+PureLayout.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/PureLayout/PureLayout+Internal.h b/Example/Pods/Headers/Private/PureLayout/PureLayout+Internal.h new file mode 120000 index 0000000..972a4ee --- /dev/null +++ b/Example/Pods/Headers/Private/PureLayout/PureLayout+Internal.h @@ -0,0 +1 @@ +../../../PureLayout/PureLayout/PureLayout/PureLayout+Internal.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/PureLayout/PureLayout.h b/Example/Pods/Headers/Private/PureLayout/PureLayout.h new file mode 120000 index 0000000..616d281 --- /dev/null +++ b/Example/Pods/Headers/Private/PureLayout/PureLayout.h @@ -0,0 +1 @@ +../../../PureLayout/PureLayout/PureLayout/PureLayout.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/PureLayout/PureLayoutDefines.h b/Example/Pods/Headers/Private/PureLayout/PureLayoutDefines.h new file mode 120000 index 0000000..4a67193 --- /dev/null +++ b/Example/Pods/Headers/Private/PureLayout/PureLayoutDefines.h @@ -0,0 +1 @@ +../../../PureLayout/PureLayout/PureLayout/PureLayoutDefines.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/TabBarPicker/TabBarItem.h b/Example/Pods/Headers/Private/TabBarPicker/TabBarItem.h new file mode 120000 index 0000000..be641b2 --- /dev/null +++ b/Example/Pods/Headers/Private/TabBarPicker/TabBarItem.h @@ -0,0 +1 @@ +../../../../../Pod/Classes/TabBarItem.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/TabBarPicker/TabBarPicker.h b/Example/Pods/Headers/Private/TabBarPicker/TabBarPicker.h new file mode 120000 index 0000000..be42cd8 --- /dev/null +++ b/Example/Pods/Headers/Private/TabBarPicker/TabBarPicker.h @@ -0,0 +1 @@ +../../../../../Pod/Classes/TabBarPicker.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/TabBarPicker/TabBarSubItem.h b/Example/Pods/Headers/Private/TabBarPicker/TabBarSubItem.h new file mode 120000 index 0000000..1a5d458 --- /dev/null +++ b/Example/Pods/Headers/Private/TabBarPicker/TabBarSubItem.h @@ -0,0 +1 @@ +../../../../../Pod/Classes/TabBarSubItem.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/pop/FloatConversion.h b/Example/Pods/Headers/Private/pop/FloatConversion.h new file mode 120000 index 0000000..aea012a --- /dev/null +++ b/Example/Pods/Headers/Private/pop/FloatConversion.h @@ -0,0 +1 @@ +../../../pop/pop/WebCore/FloatConversion.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/pop/POP.h b/Example/Pods/Headers/Private/pop/POP.h new file mode 120000 index 0000000..dd15660 --- /dev/null +++ b/Example/Pods/Headers/Private/pop/POP.h @@ -0,0 +1 @@ +../../../pop/pop/POP.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/pop/POPAction.h b/Example/Pods/Headers/Private/pop/POPAction.h new file mode 120000 index 0000000..78f9372 --- /dev/null +++ b/Example/Pods/Headers/Private/pop/POPAction.h @@ -0,0 +1 @@ +../../../pop/pop/POPAction.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/pop/POPAnimatableProperty.h b/Example/Pods/Headers/Private/pop/POPAnimatableProperty.h new file mode 120000 index 0000000..48fd8c4 --- /dev/null +++ b/Example/Pods/Headers/Private/pop/POPAnimatableProperty.h @@ -0,0 +1 @@ +../../../pop/pop/POPAnimatableProperty.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/pop/POPAnimation.h b/Example/Pods/Headers/Private/pop/POPAnimation.h new file mode 120000 index 0000000..dfe8a85 --- /dev/null +++ b/Example/Pods/Headers/Private/pop/POPAnimation.h @@ -0,0 +1 @@ +../../../pop/pop/POPAnimation.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/pop/POPAnimationEvent.h b/Example/Pods/Headers/Private/pop/POPAnimationEvent.h new file mode 120000 index 0000000..5d40492 --- /dev/null +++ b/Example/Pods/Headers/Private/pop/POPAnimationEvent.h @@ -0,0 +1 @@ +../../../pop/pop/POPAnimationEvent.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/pop/POPAnimationEventInternal.h b/Example/Pods/Headers/Private/pop/POPAnimationEventInternal.h new file mode 120000 index 0000000..8263df6 --- /dev/null +++ b/Example/Pods/Headers/Private/pop/POPAnimationEventInternal.h @@ -0,0 +1 @@ +../../../pop/pop/POPAnimationEventInternal.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/pop/POPAnimationExtras.h b/Example/Pods/Headers/Private/pop/POPAnimationExtras.h new file mode 120000 index 0000000..3a1bc7e --- /dev/null +++ b/Example/Pods/Headers/Private/pop/POPAnimationExtras.h @@ -0,0 +1 @@ +../../../pop/pop/POPAnimationExtras.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/pop/POPAnimationInternal.h b/Example/Pods/Headers/Private/pop/POPAnimationInternal.h new file mode 120000 index 0000000..6aebf45 --- /dev/null +++ b/Example/Pods/Headers/Private/pop/POPAnimationInternal.h @@ -0,0 +1 @@ +../../../pop/pop/POPAnimationInternal.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/pop/POPAnimationPrivate.h b/Example/Pods/Headers/Private/pop/POPAnimationPrivate.h new file mode 120000 index 0000000..ea5956d --- /dev/null +++ b/Example/Pods/Headers/Private/pop/POPAnimationPrivate.h @@ -0,0 +1 @@ +../../../pop/pop/POPAnimationPrivate.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/pop/POPAnimationRuntime.h b/Example/Pods/Headers/Private/pop/POPAnimationRuntime.h new file mode 120000 index 0000000..0651d06 --- /dev/null +++ b/Example/Pods/Headers/Private/pop/POPAnimationRuntime.h @@ -0,0 +1 @@ +../../../pop/pop/POPAnimationRuntime.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/pop/POPAnimationTracer.h b/Example/Pods/Headers/Private/pop/POPAnimationTracer.h new file mode 120000 index 0000000..64fff66 --- /dev/null +++ b/Example/Pods/Headers/Private/pop/POPAnimationTracer.h @@ -0,0 +1 @@ +../../../pop/pop/POPAnimationTracer.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/pop/POPAnimationTracerInternal.h b/Example/Pods/Headers/Private/pop/POPAnimationTracerInternal.h new file mode 120000 index 0000000..b76b731 --- /dev/null +++ b/Example/Pods/Headers/Private/pop/POPAnimationTracerInternal.h @@ -0,0 +1 @@ +../../../pop/pop/POPAnimationTracerInternal.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/pop/POPAnimator.h b/Example/Pods/Headers/Private/pop/POPAnimator.h new file mode 120000 index 0000000..89707ea --- /dev/null +++ b/Example/Pods/Headers/Private/pop/POPAnimator.h @@ -0,0 +1 @@ +../../../pop/pop/POPAnimator.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/pop/POPAnimatorPrivate.h b/Example/Pods/Headers/Private/pop/POPAnimatorPrivate.h new file mode 120000 index 0000000..89650c6 --- /dev/null +++ b/Example/Pods/Headers/Private/pop/POPAnimatorPrivate.h @@ -0,0 +1 @@ +../../../pop/pop/POPAnimatorPrivate.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/pop/POPBasicAnimation.h b/Example/Pods/Headers/Private/pop/POPBasicAnimation.h new file mode 120000 index 0000000..50184f2 --- /dev/null +++ b/Example/Pods/Headers/Private/pop/POPBasicAnimation.h @@ -0,0 +1 @@ +../../../pop/pop/POPBasicAnimation.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/pop/POPBasicAnimationInternal.h b/Example/Pods/Headers/Private/pop/POPBasicAnimationInternal.h new file mode 120000 index 0000000..fa8cb0b --- /dev/null +++ b/Example/Pods/Headers/Private/pop/POPBasicAnimationInternal.h @@ -0,0 +1 @@ +../../../pop/pop/POPBasicAnimationInternal.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/pop/POPCGUtils.h b/Example/Pods/Headers/Private/pop/POPCGUtils.h new file mode 120000 index 0000000..d050fb4 --- /dev/null +++ b/Example/Pods/Headers/Private/pop/POPCGUtils.h @@ -0,0 +1 @@ +../../../pop/pop/POPCGUtils.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/pop/POPCustomAnimation.h b/Example/Pods/Headers/Private/pop/POPCustomAnimation.h new file mode 120000 index 0000000..5025bd6 --- /dev/null +++ b/Example/Pods/Headers/Private/pop/POPCustomAnimation.h @@ -0,0 +1 @@ +../../../pop/pop/POPCustomAnimation.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/pop/POPDecayAnimation.h b/Example/Pods/Headers/Private/pop/POPDecayAnimation.h new file mode 120000 index 0000000..dba2796 --- /dev/null +++ b/Example/Pods/Headers/Private/pop/POPDecayAnimation.h @@ -0,0 +1 @@ +../../../pop/pop/POPDecayAnimation.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/pop/POPDecayAnimationInternal.h b/Example/Pods/Headers/Private/pop/POPDecayAnimationInternal.h new file mode 120000 index 0000000..4d5c959 --- /dev/null +++ b/Example/Pods/Headers/Private/pop/POPDecayAnimationInternal.h @@ -0,0 +1 @@ +../../../pop/pop/POPDecayAnimationInternal.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/pop/POPDefines.h b/Example/Pods/Headers/Private/pop/POPDefines.h new file mode 120000 index 0000000..4b10036 --- /dev/null +++ b/Example/Pods/Headers/Private/pop/POPDefines.h @@ -0,0 +1 @@ +../../../pop/pop/POPDefines.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/pop/POPGeometry.h b/Example/Pods/Headers/Private/pop/POPGeometry.h new file mode 120000 index 0000000..9b29189 --- /dev/null +++ b/Example/Pods/Headers/Private/pop/POPGeometry.h @@ -0,0 +1 @@ +../../../pop/pop/POPGeometry.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/pop/POPLayerExtras.h b/Example/Pods/Headers/Private/pop/POPLayerExtras.h new file mode 120000 index 0000000..e11f4c6 --- /dev/null +++ b/Example/Pods/Headers/Private/pop/POPLayerExtras.h @@ -0,0 +1 @@ +../../../pop/pop/POPLayerExtras.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/pop/POPMath.h b/Example/Pods/Headers/Private/pop/POPMath.h new file mode 120000 index 0000000..cc52b21 --- /dev/null +++ b/Example/Pods/Headers/Private/pop/POPMath.h @@ -0,0 +1 @@ +../../../pop/pop/POPMath.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/pop/POPPropertyAnimation.h b/Example/Pods/Headers/Private/pop/POPPropertyAnimation.h new file mode 120000 index 0000000..0fae4c5 --- /dev/null +++ b/Example/Pods/Headers/Private/pop/POPPropertyAnimation.h @@ -0,0 +1 @@ +../../../pop/pop/POPPropertyAnimation.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/pop/POPPropertyAnimationInternal.h b/Example/Pods/Headers/Private/pop/POPPropertyAnimationInternal.h new file mode 120000 index 0000000..5783767 --- /dev/null +++ b/Example/Pods/Headers/Private/pop/POPPropertyAnimationInternal.h @@ -0,0 +1 @@ +../../../pop/pop/POPPropertyAnimationInternal.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/pop/POPSpringAnimation.h b/Example/Pods/Headers/Private/pop/POPSpringAnimation.h new file mode 120000 index 0000000..152f663 --- /dev/null +++ b/Example/Pods/Headers/Private/pop/POPSpringAnimation.h @@ -0,0 +1 @@ +../../../pop/pop/POPSpringAnimation.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/pop/POPSpringAnimationInternal.h b/Example/Pods/Headers/Private/pop/POPSpringAnimationInternal.h new file mode 120000 index 0000000..afdc982 --- /dev/null +++ b/Example/Pods/Headers/Private/pop/POPSpringAnimationInternal.h @@ -0,0 +1 @@ +../../../pop/pop/POPSpringAnimationInternal.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/pop/POPSpringSolver.h b/Example/Pods/Headers/Private/pop/POPSpringSolver.h new file mode 120000 index 0000000..6ed1ee6 --- /dev/null +++ b/Example/Pods/Headers/Private/pop/POPSpringSolver.h @@ -0,0 +1 @@ +../../../pop/pop/POPSpringSolver.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/pop/POPVector.h b/Example/Pods/Headers/Private/pop/POPVector.h new file mode 120000 index 0000000..73f01f9 --- /dev/null +++ b/Example/Pods/Headers/Private/pop/POPVector.h @@ -0,0 +1 @@ +../../../pop/pop/POPVector.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/pop/TransformationMatrix.h b/Example/Pods/Headers/Private/pop/TransformationMatrix.h new file mode 120000 index 0000000..f1232b9 --- /dev/null +++ b/Example/Pods/Headers/Private/pop/TransformationMatrix.h @@ -0,0 +1 @@ +../../../pop/pop/WebCore/TransformationMatrix.h \ No newline at end of file diff --git a/Example/Pods/Headers/Private/pop/UnitBezier.h b/Example/Pods/Headers/Private/pop/UnitBezier.h new file mode 120000 index 0000000..fbd11a0 --- /dev/null +++ b/Example/Pods/Headers/Private/pop/UnitBezier.h @@ -0,0 +1 @@ +../../../pop/pop/WebCore/UnitBezier.h \ No newline at end of file diff --git a/Example/Pods/Headers/Public/FBSnapshotTestCase/FBSnapshotTestCase.h b/Example/Pods/Headers/Public/FBSnapshotTestCase/FBSnapshotTestCase.h new file mode 120000 index 0000000..2925eab --- /dev/null +++ b/Example/Pods/Headers/Public/FBSnapshotTestCase/FBSnapshotTestCase.h @@ -0,0 +1 @@ +../../../FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestCase.h \ No newline at end of file diff --git a/Example/Pods/Headers/Public/FBSnapshotTestCase/FBSnapshotTestCasePlatform.h b/Example/Pods/Headers/Public/FBSnapshotTestCase/FBSnapshotTestCasePlatform.h new file mode 120000 index 0000000..6127a30 --- /dev/null +++ b/Example/Pods/Headers/Public/FBSnapshotTestCase/FBSnapshotTestCasePlatform.h @@ -0,0 +1 @@ +../../../FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestCasePlatform.h \ No newline at end of file diff --git a/Example/Pods/Headers/Public/FBSnapshotTestCase/FBSnapshotTestController.h b/Example/Pods/Headers/Public/FBSnapshotTestCase/FBSnapshotTestController.h new file mode 120000 index 0000000..4a7dea1 --- /dev/null +++ b/Example/Pods/Headers/Public/FBSnapshotTestCase/FBSnapshotTestController.h @@ -0,0 +1 @@ +../../../FBSnapshotTestCase/FBSnapshotTestCase/FBSnapshotTestController.h \ No newline at end of file diff --git a/Example/Pods/Headers/Public/FBSnapshotTestCase/UIImage+Compare.h b/Example/Pods/Headers/Public/FBSnapshotTestCase/UIImage+Compare.h new file mode 120000 index 0000000..a68eafb --- /dev/null +++ b/Example/Pods/Headers/Public/FBSnapshotTestCase/UIImage+Compare.h @@ -0,0 +1 @@ +../../../FBSnapshotTestCase/FBSnapshotTestCase/UIImage+Compare.h \ No newline at end of file diff --git a/Example/Pods/Headers/Public/FBSnapshotTestCase/UIImage+Diff.h b/Example/Pods/Headers/Public/FBSnapshotTestCase/UIImage+Diff.h new file mode 120000 index 0000000..f21e64d --- /dev/null +++ b/Example/Pods/Headers/Public/FBSnapshotTestCase/UIImage+Diff.h @@ -0,0 +1 @@ +../../../FBSnapshotTestCase/FBSnapshotTestCase/UIImage+Diff.h \ No newline at end of file diff --git a/Example/Pods/Headers/Public/PureLayout/ALView+PureLayout.h b/Example/Pods/Headers/Public/PureLayout/ALView+PureLayout.h new file mode 120000 index 0000000..ac489e2 --- /dev/null +++ b/Example/Pods/Headers/Public/PureLayout/ALView+PureLayout.h @@ -0,0 +1 @@ +../../../PureLayout/PureLayout/PureLayout/ALView+PureLayout.h \ No newline at end of file diff --git a/Example/Pods/Headers/Public/PureLayout/NSArray+PureLayout.h b/Example/Pods/Headers/Public/PureLayout/NSArray+PureLayout.h new file mode 120000 index 0000000..76395e6 --- /dev/null +++ b/Example/Pods/Headers/Public/PureLayout/NSArray+PureLayout.h @@ -0,0 +1 @@ +../../../PureLayout/PureLayout/PureLayout/NSArray+PureLayout.h \ No newline at end of file diff --git a/Example/Pods/Headers/Public/PureLayout/NSLayoutConstraint+PureLayout.h b/Example/Pods/Headers/Public/PureLayout/NSLayoutConstraint+PureLayout.h new file mode 120000 index 0000000..a2afdda --- /dev/null +++ b/Example/Pods/Headers/Public/PureLayout/NSLayoutConstraint+PureLayout.h @@ -0,0 +1 @@ +../../../PureLayout/PureLayout/PureLayout/NSLayoutConstraint+PureLayout.h \ No newline at end of file diff --git a/Example/Pods/Headers/Public/PureLayout/PureLayout+Internal.h b/Example/Pods/Headers/Public/PureLayout/PureLayout+Internal.h new file mode 120000 index 0000000..972a4ee --- /dev/null +++ b/Example/Pods/Headers/Public/PureLayout/PureLayout+Internal.h @@ -0,0 +1 @@ +../../../PureLayout/PureLayout/PureLayout/PureLayout+Internal.h \ No newline at end of file diff --git a/Example/Pods/Headers/Public/PureLayout/PureLayout.h b/Example/Pods/Headers/Public/PureLayout/PureLayout.h new file mode 120000 index 0000000..616d281 --- /dev/null +++ b/Example/Pods/Headers/Public/PureLayout/PureLayout.h @@ -0,0 +1 @@ +../../../PureLayout/PureLayout/PureLayout/PureLayout.h \ No newline at end of file diff --git a/Example/Pods/Headers/Public/PureLayout/PureLayoutDefines.h b/Example/Pods/Headers/Public/PureLayout/PureLayoutDefines.h new file mode 120000 index 0000000..4a67193 --- /dev/null +++ b/Example/Pods/Headers/Public/PureLayout/PureLayoutDefines.h @@ -0,0 +1 @@ +../../../PureLayout/PureLayout/PureLayout/PureLayoutDefines.h \ No newline at end of file diff --git a/Example/Pods/Headers/Public/TabBarPicker/TabBarItem.h b/Example/Pods/Headers/Public/TabBarPicker/TabBarItem.h new file mode 120000 index 0000000..be641b2 --- /dev/null +++ b/Example/Pods/Headers/Public/TabBarPicker/TabBarItem.h @@ -0,0 +1 @@ +../../../../../Pod/Classes/TabBarItem.h \ No newline at end of file diff --git a/Example/Pods/Headers/Public/TabBarPicker/TabBarPicker.h b/Example/Pods/Headers/Public/TabBarPicker/TabBarPicker.h new file mode 120000 index 0000000..be42cd8 --- /dev/null +++ b/Example/Pods/Headers/Public/TabBarPicker/TabBarPicker.h @@ -0,0 +1 @@ +../../../../../Pod/Classes/TabBarPicker.h \ No newline at end of file diff --git a/Example/Pods/Headers/Public/TabBarPicker/TabBarSubItem.h b/Example/Pods/Headers/Public/TabBarPicker/TabBarSubItem.h new file mode 120000 index 0000000..1a5d458 --- /dev/null +++ b/Example/Pods/Headers/Public/TabBarPicker/TabBarSubItem.h @@ -0,0 +1 @@ +../../../../../Pod/Classes/TabBarSubItem.h \ No newline at end of file diff --git a/Example/Pods/Headers/Public/pop/POP.h b/Example/Pods/Headers/Public/pop/POP.h new file mode 120000 index 0000000..dd15660 --- /dev/null +++ b/Example/Pods/Headers/Public/pop/POP.h @@ -0,0 +1 @@ +../../../pop/pop/POP.h \ No newline at end of file diff --git a/Example/Pods/Headers/Public/pop/POPAnimatableProperty.h b/Example/Pods/Headers/Public/pop/POPAnimatableProperty.h new file mode 120000 index 0000000..48fd8c4 --- /dev/null +++ b/Example/Pods/Headers/Public/pop/POPAnimatableProperty.h @@ -0,0 +1 @@ +../../../pop/pop/POPAnimatableProperty.h \ No newline at end of file diff --git a/Example/Pods/Headers/Public/pop/POPAnimation.h b/Example/Pods/Headers/Public/pop/POPAnimation.h new file mode 120000 index 0000000..dfe8a85 --- /dev/null +++ b/Example/Pods/Headers/Public/pop/POPAnimation.h @@ -0,0 +1 @@ +../../../pop/pop/POPAnimation.h \ No newline at end of file diff --git a/Example/Pods/Headers/Public/pop/POPAnimationEvent.h b/Example/Pods/Headers/Public/pop/POPAnimationEvent.h new file mode 120000 index 0000000..5d40492 --- /dev/null +++ b/Example/Pods/Headers/Public/pop/POPAnimationEvent.h @@ -0,0 +1 @@ +../../../pop/pop/POPAnimationEvent.h \ No newline at end of file diff --git a/Example/Pods/Headers/Public/pop/POPAnimationExtras.h b/Example/Pods/Headers/Public/pop/POPAnimationExtras.h new file mode 120000 index 0000000..3a1bc7e --- /dev/null +++ b/Example/Pods/Headers/Public/pop/POPAnimationExtras.h @@ -0,0 +1 @@ +../../../pop/pop/POPAnimationExtras.h \ No newline at end of file diff --git a/Example/Pods/Headers/Public/pop/POPAnimationTracer.h b/Example/Pods/Headers/Public/pop/POPAnimationTracer.h new file mode 120000 index 0000000..64fff66 --- /dev/null +++ b/Example/Pods/Headers/Public/pop/POPAnimationTracer.h @@ -0,0 +1 @@ +../../../pop/pop/POPAnimationTracer.h \ No newline at end of file diff --git a/Example/Pods/Headers/Public/pop/POPAnimator.h b/Example/Pods/Headers/Public/pop/POPAnimator.h new file mode 120000 index 0000000..89707ea --- /dev/null +++ b/Example/Pods/Headers/Public/pop/POPAnimator.h @@ -0,0 +1 @@ +../../../pop/pop/POPAnimator.h \ No newline at end of file diff --git a/Example/Pods/Headers/Public/pop/POPBasicAnimation.h b/Example/Pods/Headers/Public/pop/POPBasicAnimation.h new file mode 120000 index 0000000..50184f2 --- /dev/null +++ b/Example/Pods/Headers/Public/pop/POPBasicAnimation.h @@ -0,0 +1 @@ +../../../pop/pop/POPBasicAnimation.h \ No newline at end of file diff --git a/Example/Pods/Headers/Public/pop/POPCustomAnimation.h b/Example/Pods/Headers/Public/pop/POPCustomAnimation.h new file mode 120000 index 0000000..5025bd6 --- /dev/null +++ b/Example/Pods/Headers/Public/pop/POPCustomAnimation.h @@ -0,0 +1 @@ +../../../pop/pop/POPCustomAnimation.h \ No newline at end of file diff --git a/Example/Pods/Headers/Public/pop/POPDecayAnimation.h b/Example/Pods/Headers/Public/pop/POPDecayAnimation.h new file mode 120000 index 0000000..dba2796 --- /dev/null +++ b/Example/Pods/Headers/Public/pop/POPDecayAnimation.h @@ -0,0 +1 @@ +../../../pop/pop/POPDecayAnimation.h \ No newline at end of file diff --git a/Example/Pods/Headers/Public/pop/POPDefines.h b/Example/Pods/Headers/Public/pop/POPDefines.h new file mode 120000 index 0000000..4b10036 --- /dev/null +++ b/Example/Pods/Headers/Public/pop/POPDefines.h @@ -0,0 +1 @@ +../../../pop/pop/POPDefines.h \ No newline at end of file diff --git a/Example/Pods/Headers/Public/pop/POPGeometry.h b/Example/Pods/Headers/Public/pop/POPGeometry.h new file mode 120000 index 0000000..9b29189 --- /dev/null +++ b/Example/Pods/Headers/Public/pop/POPGeometry.h @@ -0,0 +1 @@ +../../../pop/pop/POPGeometry.h \ No newline at end of file diff --git a/Example/Pods/Headers/Public/pop/POPLayerExtras.h b/Example/Pods/Headers/Public/pop/POPLayerExtras.h new file mode 120000 index 0000000..e11f4c6 --- /dev/null +++ b/Example/Pods/Headers/Public/pop/POPLayerExtras.h @@ -0,0 +1 @@ +../../../pop/pop/POPLayerExtras.h \ No newline at end of file diff --git a/Example/Pods/Headers/Public/pop/POPPropertyAnimation.h b/Example/Pods/Headers/Public/pop/POPPropertyAnimation.h new file mode 120000 index 0000000..0fae4c5 --- /dev/null +++ b/Example/Pods/Headers/Public/pop/POPPropertyAnimation.h @@ -0,0 +1 @@ +../../../pop/pop/POPPropertyAnimation.h \ No newline at end of file diff --git a/Example/Pods/Headers/Public/pop/POPSpringAnimation.h b/Example/Pods/Headers/Public/pop/POPSpringAnimation.h new file mode 120000 index 0000000..152f663 --- /dev/null +++ b/Example/Pods/Headers/Public/pop/POPSpringAnimation.h @@ -0,0 +1 @@ +../../../pop/pop/POPSpringAnimation.h \ No newline at end of file diff --git a/Example/Pods/Local Podspecs/TabBarPicker.podspec.json b/Example/Pods/Local Podspecs/TabBarPicker.podspec.json new file mode 100644 index 0000000..dba5ee8 --- /dev/null +++ b/Example/Pods/Local Podspecs/TabBarPicker.podspec.json @@ -0,0 +1,25 @@ +{ + "name": "TabBarPicker", + "version": "0.1.0", + "summary": "A short description of TabBarPicker.", + "description": " An optional longer description of TabBarPicker\n\n * Markdown format.\n * Don't worry about the indent, we strip it!\n", + "homepage": "https://github.com//TabBarPicker", + "license": "MIT", + "authors": { + "Giuseppe Nucifora": "me@giuseppenucifora.com" + }, + "source": { + "git": "https://github.com//TabBarPicker.git", + "tag": "0.1.0" + }, + "platforms": { + "ios": "7.0" + }, + "requires_arc": true, + "source_files": "Pod/Classes/**/*", + "resource_bundles": { + "TabBarPicker": [ + "Pod/Assets/*.png" + ] + } +} diff --git a/Example/Pods/Manifest.lock b/Example/Pods/Manifest.lock new file mode 100644 index 0000000..dbf2dd0 --- /dev/null +++ b/Example/Pods/Manifest.lock @@ -0,0 +1,27 @@ +PODS: + - FBSnapshotTestCase (2.0.2): + - FBSnapshotTestCase/SwiftSupport (= 2.0.2) + - FBSnapshotTestCase/Core (2.0.2) + - FBSnapshotTestCase/SwiftSupport (2.0.2): + - FBSnapshotTestCase/Core + - pop (1.0.7) + - PureLayout (2.0.6) + - TabBarPicker (0.1.0) + +DEPENDENCIES: + - FBSnapshotTestCase + - pop (~> 1.0) + - PureLayout + - TabBarPicker (from `../`) + +EXTERNAL SOURCES: + TabBarPicker: + :path: ../ + +SPEC CHECKSUMS: + FBSnapshotTestCase: fd500d5b282c4ec60215d26d0b58b0cf271dd0d6 + pop: 628ffc631644601567ee8bfaaaea493ebd7d0923 + PureLayout: f25f0bb904d5ccfe6e31da3cb869185259f02e0d + TabBarPicker: f26d10a5d9f460b5a5a2d5ce5b48635c802577c5 + +COCOAPODS: 0.37.2 diff --git a/Example/Pods/Pods.xcodeproj/project.pbxproj b/Example/Pods/Pods.xcodeproj/project.pbxproj new file mode 100644 index 0000000..8c56d80 --- /dev/null +++ b/Example/Pods/Pods.xcodeproj/project.pbxproj @@ -0,0 +1,1815 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 00618A922B4BF903CD3FB0FB /* ALView+PureLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = 20DAEFB09BBB3604EF2B6FAC /* ALView+PureLayout.m */; }; + 056FF56B0E3FFCD1569FE5FA /* POPAnimationRuntime.mm in Sources */ = {isa = PBXBuildFile; fileRef = D2A821FBF4A3AC98022EE500 /* POPAnimationRuntime.mm */; }; + 08E83A3AAFD5A55C25D691EB /* TabBarPicker.m in Sources */ = {isa = PBXBuildFile; fileRef = 624F4B8D72BCA2E5B0B97961 /* TabBarPicker.m */; }; + 09A4D4FD25C7CF71000BFD2F /* POPAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = BFC8C255D5605A64BC77DDCE /* POPAnimation.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 09CF26836A1B5FFE7F41C3EB /* TabBarSubItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 97AA84C2A069A2176400C2DE /* TabBarSubItem.m */; }; + 0AB2B13C89C0504EA2809C41 /* POPAnimatableProperty.mm in Sources */ = {isa = PBXBuildFile; fileRef = 65A05347063995FDAF01B670 /* POPAnimatableProperty.mm */; }; + 0E6A3ED7F51A2B603FC8AA84 /* TransformationMatrix.h in Headers */ = {isa = PBXBuildFile; fileRef = B7FEAF540E638E9AEB5DAF2A /* TransformationMatrix.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 0E6AA18FEDB5F876D193D4A0 /* TransformationMatrix.cpp in Sources */ = {isa = PBXBuildFile; fileRef = F712C1311B5EE5C36D455BD0 /* TransformationMatrix.cpp */; }; + 0F8A059B32D797853970DD24 /* PureLayout+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 2BA42E3BA28325313FB2B2A3 /* PureLayout+Internal.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 100967E31D4539EDC982A5DB /* NSArray+PureLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = 4C6270ED8D95D5EDF4008F37 /* NSArray+PureLayout.m */; }; + 108142577EB2C6F99ADA8C61 /* POPAnimationEventInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 5885BAE70442B3B09EDAA0EE /* POPAnimationEventInternal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 10CD87106DC803FFAE595FF3 /* POPBasicAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 685A2F2C951CB89EDD363751 /* POPBasicAnimation.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 124D751F1A50BADA38571F52 /* TabBarPicker.h in Headers */ = {isa = PBXBuildFile; fileRef = 148DB42881C2CA9E8E5EE6E1 /* TabBarPicker.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 14F43215C15DD385DC37FCC7 /* POPGeometry.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A5344894FEF98D9616959AF /* POPGeometry.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 162BEA745AAA759206480273 /* POPPropertyAnimationInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = E03638B659A2C5164CF04D30 /* POPPropertyAnimationInternal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 16D4A319EB5B6BA724F18A14 /* Pods-TabBarPicker_Tests-PureLayout-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = B507E9F463795031E3CEA800 /* Pods-TabBarPicker_Tests-PureLayout-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 19E2E13BF272C622A6212CDF /* NSLayoutConstraint+PureLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = D70593152E0AAA16D569EAA1 /* NSLayoutConstraint+PureLayout.m */; }; + 1B7951918B590B9BE7451E47 /* POPSpringAnimation.mm in Sources */ = {isa = PBXBuildFile; fileRef = 544127507DF529D623BCD492 /* POPSpringAnimation.mm */; }; + 1E8C432521038851EDD5B9F3 /* PureLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = E952AE82AA42C9BBBE86C72B /* PureLayout.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2116A6EA200DC1D2328AB03A /* Pods-TabBarPicker_Tests-pop-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = BDF1FD88252CA3BCEBBAC8FF /* Pods-TabBarPicker_Tests-pop-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 238EC5BEDA39C6E0C2C86E02 /* POPGeometry.mm in Sources */ = {isa = PBXBuildFile; fileRef = 22F51E2B500C2FF5D08D50C0 /* POPGeometry.mm */; }; + 24ABCA32BE6380A98CF98E28 /* NSLayoutConstraint+PureLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 76BB8DE64767732CFE4A8B40 /* NSLayoutConstraint+PureLayout.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 27A0DF5F969CB972F019D658 /* TabBarSubItem.h in Headers */ = {isa = PBXBuildFile; fileRef = F38CB30BE32060FBD8C51A75 /* TabBarSubItem.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2DB8E0125011E2555B599F6F /* FBSnapshotTestCase.h in Headers */ = {isa = PBXBuildFile; fileRef = A2E37F810A8B379AF9A5ED62 /* FBSnapshotTestCase.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 2E5474CD0D2321F240A9DFE8 /* POPVector.h in Headers */ = {isa = PBXBuildFile; fileRef = 413FD75D9BC7519CFE72E73B /* POPVector.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 324C7320C2ABF43BA6DEEFFE /* POPCustomAnimation.mm in Sources */ = {isa = PBXBuildFile; fileRef = FA8D04C3ECD5B2B3C79AF0FD /* POPCustomAnimation.mm */; }; + 33C553DA18FDC7D9B3978AB1 /* POPAnimationRuntime.h in Headers */ = {isa = PBXBuildFile; fileRef = 3C1E962465F636A50709B5CB /* POPAnimationRuntime.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 352A750A926CD6A3FD798789 /* TabBarPicker.bundle in Resources */ = {isa = PBXBuildFile; fileRef = D645E5697216C1033B02AFF8 /* TabBarPicker.bundle */; }; + 3B3B0386FC06E752FE9DAAC5 /* Pods-TabBarPicker_Tests-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 3FEB087DA29AB726C4E4DD1E /* Pods-TabBarPicker_Tests-dummy.m */; }; + 3B3B3B4D7F1F2407A7BB8F06 /* POPPropertyAnimation.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8C709287CB08F14A495E907E /* POPPropertyAnimation.mm */; }; + 3BD54709283F3AACAABAEF9B /* POPAnimationInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = B247360918A92665C18E2F93 /* POPAnimationInternal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 3E6ABA6E976EE9F358D84207 /* TabBarPicker.m in Sources */ = {isa = PBXBuildFile; fileRef = 624F4B8D72BCA2E5B0B97961 /* TabBarPicker.m */; }; + 3EE6AB8DD62DB60E64D05A0C /* POPAnimationPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 8CD00ACD98CB3EF2D5A11D2B /* POPAnimationPrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 44933988DCE544FCDE73C91C /* Pods-TabBarPicker_Tests-TabBarPicker-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 9332766E99EE0F5D2A1FBA61 /* Pods-TabBarPicker_Tests-TabBarPicker-dummy.m */; }; + 45625B69AC49546CDDF3354E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 836C19BF80C4FF0F04846DAE /* Foundation.framework */; }; + 491B2C383677E49A8B176870 /* Pods-TabBarPicker_Tests-pop-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = C046D94936BFF08C7EB8A799 /* Pods-TabBarPicker_Tests-pop-dummy.m */; }; + 4F168F8645C1E934DD6F1BC2 /* POPCustomAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C154F503C254677106143FA /* POPCustomAnimation.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 519595A4F772637BFA8F84B7 /* POPMath.h in Headers */ = {isa = PBXBuildFile; fileRef = D67D2099C65F165EB6A984A3 /* POPMath.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 53160D4212932FC7C56D3EF2 /* POPAnimatableProperty.h in Headers */ = {isa = PBXBuildFile; fileRef = E900DEC840C6736872C2F7A3 /* POPAnimatableProperty.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 55D74730D1FB242A78A3C0E2 /* POPAnimationEvent.h in Headers */ = {isa = PBXBuildFile; fileRef = D9DED1AB470D76F7CAA0E99B /* POPAnimationEvent.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 58202E9C720A5DA7AC69572C /* POPPropertyAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = E5D8B474F14DDE4F4D52409E /* POPPropertyAnimation.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 58C14E475C19C9C5F963EBAF /* Pods-TabBarPicker_Tests-FBSnapshotTestCase-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 76CBBC331037069F49A1481B /* Pods-TabBarPicker_Tests-FBSnapshotTestCase-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 58F869B2B16B8D3A5BE0A964 /* POPSpringAnimationInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = A33E846EF6A35C4CEB1811B3 /* POPSpringAnimationInternal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 5A94D7E53BF242DED78CFAA0 /* POPAnimationTracerInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = EA227E173AB2AE183693AE43 /* POPAnimationTracerInternal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 5C89C0AA72C233E829573398 /* TabBarPicker.h in Headers */ = {isa = PBXBuildFile; fileRef = 148DB42881C2CA9E8E5EE6E1 /* TabBarPicker.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5CBC2056C4A92853FB8D6FC1 /* FBSnapshotTestController.m in Sources */ = {isa = PBXBuildFile; fileRef = EEBDC1DFE7F73BBFA25A3874 /* FBSnapshotTestController.m */; }; + 5D73A845AC7211A277B2B3B4 /* POPAnimationTracer.h in Headers */ = {isa = PBXBuildFile; fileRef = 89A1433A66EAC56F78C55709 /* POPAnimationTracer.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 61852B1EC5A79D61D09833D8 /* Pods-TabBarPicker_Tests-PureLayout-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = E42D397953D1C3C95F9408EC /* Pods-TabBarPicker_Tests-PureLayout-dummy.m */; }; + 6223D7701E616A12B9886220 /* Pods-TabBarPicker_Tests-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 5AD1999225A10120E5B02995 /* Pods-TabBarPicker_Tests-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 62E823E5143EB6A31CA83F64 /* NSArray+PureLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = A7B7E6397D072295FE0A5F54 /* NSArray+PureLayout.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 63284F345CEB86A51188CD4C /* POPAnimation.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7CE93A7A2D53987E699A82E0 /* POPAnimation.mm */; }; + 65B31B3C4504F32874FBFD98 /* POPAnimatorPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 937BA8EE0828B170DD0E088B /* POPAnimatorPrivate.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 6629264412C2FE52A1169348 /* UnitBezier.h in Headers */ = {isa = PBXBuildFile; fileRef = 5937D50E458DE19FAFF1C2CB /* UnitBezier.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 6636FFF6FFBCCE668F3E9F87 /* POPDecayAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = 0621F69BD40BD272EB5A92E6 /* POPDecayAnimation.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 69EF0AF9146AABC83DD15197 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 836C19BF80C4FF0F04846DAE /* Foundation.framework */; }; + 6AF6567DABEF6C271FBB18EF /* Pods-TabBarPicker_Tests-FBSnapshotTestCase-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 4AC1B5068EBE1625BCF263B5 /* Pods-TabBarPicker_Tests-FBSnapshotTestCase-dummy.m */; }; + 6C1750B6604BA8C954F15225 /* POPLayerExtras.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0EE713E3695F83812F704460 /* POPLayerExtras.mm */; }; + 6C7DD001B76A2341D3B3516A /* POPCGUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = EE4A88A51750716CC9AB53D9 /* POPCGUtils.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 6C7EC292AC2406906C89C702 /* TabBarItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 2ADB8B46D2F315D0F612EE6D /* TabBarItem.m */; }; + 6E93B61EB2DEDE0964E3B1EE /* Pods-TabBarPicker_Tests-TabBarPicker-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 483BA47373CDB5DCE7469742 /* Pods-TabBarPicker_Tests-TabBarPicker-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6F4F6E1692E952C3DF70CC77 /* FBSnapshotTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 85D051E1BBACBD2556FEDC84 /* FBSnapshotTestCase.m */; }; + 7247D3BD1744F25683AD5F8D /* POPAction.h in Headers */ = {isa = PBXBuildFile; fileRef = 428D4B3163A29F10062580F2 /* POPAction.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 777C0B3EE3BF68B1B878885A /* FBSnapshotTestCasePlatform.h in Headers */ = {isa = PBXBuildFile; fileRef = B5700F2D4F531E07A88381D3 /* FBSnapshotTestCasePlatform.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 77ADA9D3C1DB1B0AEDFF1113 /* POPDecayAnimationInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = FD6E18FA54DF8FB7CF9BCE73 /* POPDecayAnimationInternal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 7A23C9B612EBF9AD343CE1E2 /* FloatConversion.h in Headers */ = {isa = PBXBuildFile; fileRef = 3467B4DD11D47F7D324E3BCC /* FloatConversion.h */; settings = {ATTRIBUTES = (Project, ); }; }; + 7E2F911B68DDD100F76D2D90 /* POPAnimationExtras.h in Headers */ = {isa = PBXBuildFile; fileRef = D81EB44F93B7D8FCBB471993 /* POPAnimationExtras.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 7EEFD4EEF35DCB13D8049996 /* POPAnimator.h in Headers */ = {isa = PBXBuildFile; fileRef = 1FFBBE368E09DDA2C9F47256 /* POPAnimator.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 85DEB4C5BC1A258172B2D9C9 /* Pods-TabBarPicker_Example-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CE25E08DA798F46C5C345BD /* Pods-TabBarPicker_Example-dummy.m */; }; + 87E34772E3D5DC2A38D13DCC /* TabBarSubItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 97AA84C2A069A2176400C2DE /* TabBarSubItem.m */; }; + 8F4C1C2AB5F72BD79C715288 /* SwiftSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0CA996C8534E12C67AFFCB4 /* SwiftSupport.swift */; }; + 90FCFA53B151BE9EFDCB409B /* POP.h in Headers */ = {isa = PBXBuildFile; fileRef = 02A5AABEEC9D765E78544C8A /* POP.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 912985F63EFD09B575DF6149 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 836C19BF80C4FF0F04846DAE /* Foundation.framework */; }; + 9647BD594D454AA36B317BCA /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 836C19BF80C4FF0F04846DAE /* Foundation.framework */; }; + 9668EE579FCE6F10E8E7530B /* POPAnimationTracer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0EAD06508EAD678C349CAA93 /* POPAnimationTracer.mm */; }; + A44C43086F269C7D7447CB70 /* POPBasicAnimation.mm in Sources */ = {isa = PBXBuildFile; fileRef = 899203F65224A417FA8DF792 /* POPBasicAnimation.mm */; }; + A8ABDEDC714A994B6B36A4F1 /* Pods-TabBarPicker_Example-TabBarPicker-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = E4BAA120AA13A1D02FAA23A4 /* Pods-TabBarPicker_Example-TabBarPicker-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + B116AAD6A555AEA1B6301C0B /* POPVector.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4F9248C014BA85DA9E62985C /* POPVector.mm */; }; + B1514CE9C56F3D9A14947483 /* UIImage+Diff.h in Headers */ = {isa = PBXBuildFile; fileRef = 494A2E44D3C1B4593C09F080 /* UIImage+Diff.h */; settings = {ATTRIBUTES = (Public, ); }; }; + B4998C8B2DFBD10D384BEDAB /* UIImage+Compare.m in Sources */ = {isa = PBXBuildFile; fileRef = CAB8D808D64C356B89F2B4F2 /* UIImage+Compare.m */; }; + B858BAD455D0DB8F907F3128 /* POPSpringAnimation.h in Headers */ = {isa = PBXBuildFile; fileRef = F055371F054FE9B88F18F289 /* POPSpringAnimation.h */; settings = {ATTRIBUTES = (Public, ); }; }; + BEE9747F66B393FEEFE81E35 /* TabBarItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 1371413CE12B3C17738BA8D2 /* TabBarItem.h */; settings = {ATTRIBUTES = (Public, ); }; }; + C108F31F0426C3C4141B2A3A /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0A709C0164EDF439E429804C /* XCTest.framework */; }; + C230EF663C8B2E9AA75BB7C7 /* POPSpringSolver.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A20EB35B02DAC09E6DB5A03 /* POPSpringSolver.h */; settings = {ATTRIBUTES = (Project, ); }; }; + C24C05FE7938E208BC25AB47 /* Pods-TabBarPicker_Example-TabBarPicker-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 271C3F17E60FF4A971EB7D6C /* Pods-TabBarPicker_Example-TabBarPicker-dummy.m */; }; + C3D2D049AB16D5AB12B9D2D4 /* UIImage+Diff.m in Sources */ = {isa = PBXBuildFile; fileRef = 384CEA765776C7069B6E3A0A /* UIImage+Diff.m */; }; + C4A5D52AB2139FA5A09919D9 /* POPLayerExtras.h in Headers */ = {isa = PBXBuildFile; fileRef = 3F75A1B9295C04A7E96EF69E /* POPLayerExtras.h */; settings = {ATTRIBUTES = (Public, ); }; }; + C591C499E7FB0CF3D776512B /* TabBarItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 1371413CE12B3C17738BA8D2 /* TabBarItem.h */; settings = {ATTRIBUTES = (Public, ); }; }; + CD7065E574AC2C89F9C3C91E /* POPAnimator.mm in Sources */ = {isa = PBXBuildFile; fileRef = A1BC25112DD2DB4E6681FCAF /* POPAnimator.mm */; }; + CDC7C637CE560B20F11D500B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 836C19BF80C4FF0F04846DAE /* Foundation.framework */; }; + D15A957FA849695B2BC0E2BA /* TabBarSubItem.h in Headers */ = {isa = PBXBuildFile; fileRef = F38CB30BE32060FBD8C51A75 /* TabBarSubItem.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D3052435A90B887C4E7AEAC0 /* FBSnapshotTestController.h in Headers */ = {isa = PBXBuildFile; fileRef = F09E62CF4421B4574210C522 /* FBSnapshotTestController.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D32535025C6A0066C7FDF4C7 /* Pods-TabBarPicker_Example-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = AD58BB786DB0FA8E5986CF62 /* Pods-TabBarPicker_Example-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D4B8AA680BDB18DE67139A6C /* PureLayoutDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = B7B8C5A5AD41DCC1AA5383DD /* PureLayoutDefines.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D4D8565B5B52B5E6C0D1E23E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 836C19BF80C4FF0F04846DAE /* Foundation.framework */; }; + D713143B8698238B22FF78F8 /* POPCGUtils.mm in Sources */ = {isa = PBXBuildFile; fileRef = D72B37CBCBB5AC9907A07492 /* POPCGUtils.mm */; }; + D87F6826919FDDA6D85A58A7 /* POPBasicAnimationInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = FFCA0749279D282CA89A3BBB /* POPBasicAnimationInternal.h */; settings = {ATTRIBUTES = (Project, ); }; }; + D9249B401EAFBC7E735A59E1 /* POPDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = 647AEE8412687956E96EC00C /* POPDefines.h */; settings = {ATTRIBUTES = (Public, ); }; }; + DED28AA986D5385272CCB19A /* POPMath.mm in Sources */ = {isa = PBXBuildFile; fileRef = 6B80285B23944F6871DB8605 /* POPMath.mm */; }; + DF4005BF055A0E8B8ED44A2E /* FBSnapshotTestCasePlatform.m in Sources */ = {isa = PBXBuildFile; fileRef = 2D2A49D478E89B97BAC285F9 /* FBSnapshotTestCasePlatform.m */; }; + DFFD167800AA5C7FB04156CE /* TabBarPicker.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 8E8E7A5081A9B7120430EB1C /* TabBarPicker.bundle */; }; + E03EE333F599DDEAC8D54CBA /* TabBarItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 2ADB8B46D2F315D0F612EE6D /* TabBarItem.m */; }; + E1646D029B083ACD4AA09A1A /* POPAnimationEvent.mm in Sources */ = {isa = PBXBuildFile; fileRef = F9272C6C8510653C958CE89A /* POPAnimationEvent.mm */; }; + E171CC4952BB865125F56FC4 /* ALView+PureLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = C5BBC4E67C2F854A90B1F635 /* ALView+PureLayout.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E273ABADFA0DFA5557EDFE90 /* POPDecayAnimation.mm in Sources */ = {isa = PBXBuildFile; fileRef = A79541B5C564B095A7F4DF34 /* POPDecayAnimation.mm */; }; + F2E41845989F5902E0EA80F2 /* POPAnimationExtras.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2CE514EAF053F4D716B7AAD9 /* POPAnimationExtras.mm */; }; + F66B3044416BCD206343E08A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 836C19BF80C4FF0F04846DAE /* Foundation.framework */; }; + FD8BF6D2DA1679CE61A6F527 /* UIImage+Compare.h in Headers */ = {isa = PBXBuildFile; fileRef = 37709ECBB155458EFBFFED39 /* UIImage+Compare.h */; settings = {ATTRIBUTES = (Public, ); }; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 0EA9D3ECCF74DE7F75274BD5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D9442BE4A2137345B01F164F /* Project object */; + proxyType = 1; + remoteGlobalIDString = 3998475720C1C47684180202; + remoteInfo = "Pods-TabBarPicker_Tests-PureLayout"; + }; + 1530225FC7A44B1ACA588ECC /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D9442BE4A2137345B01F164F /* Project object */; + proxyType = 1; + remoteGlobalIDString = 8CA46A24F79F8A2591154DC8; + remoteInfo = "Pods-TabBarPicker_Example-TabBarPicker-TabBarPicker"; + }; + 6A2372653D3E44E2B0D68BC9 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D9442BE4A2137345B01F164F /* Project object */; + proxyType = 1; + remoteGlobalIDString = 561939E4515B71341136E16E; + remoteInfo = "Pods-TabBarPicker_Tests-TabBarPicker"; + }; + 851C37FE16A19DB70AA57891 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D9442BE4A2137345B01F164F /* Project object */; + proxyType = 1; + remoteGlobalIDString = C26F15991223F90FD04DB84A; + remoteInfo = "Pods-TabBarPicker_Tests-TabBarPicker-TabBarPicker"; + }; + B025178FEAD646D2229BDD0B /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D9442BE4A2137345B01F164F /* Project object */; + proxyType = 1; + remoteGlobalIDString = AE841CD8269D52D367EBAEBB; + remoteInfo = "Pods-TabBarPicker_Example-TabBarPicker"; + }; + B244F2E681508765E9F87E57 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D9442BE4A2137345B01F164F /* Project object */; + proxyType = 1; + remoteGlobalIDString = 25EC7DE4FAEEEF84395686BD; + remoteInfo = "Pods-TabBarPicker_Tests-FBSnapshotTestCase"; + }; + F28FCFE320A7C1F1C2A78D0E /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D9442BE4A2137345B01F164F /* Project object */; + proxyType = 1; + remoteGlobalIDString = CF3DCEB04961FDED1CAC4B7D; + remoteInfo = "Pods-TabBarPicker_Tests-pop"; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 02A5AABEEC9D765E78544C8A /* POP.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = POP.h; path = pop/POP.h; sourceTree = ""; }; + 032060E06DB91F8976AB60CF /* Pods-TabBarPicker_Tests-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-TabBarPicker_Tests-frameworks.sh"; sourceTree = ""; }; + 0621F69BD40BD272EB5A92E6 /* POPDecayAnimation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = POPDecayAnimation.h; path = pop/POPDecayAnimation.h; sourceTree = ""; }; + 0A709C0164EDF439E429804C /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.3.sdk/System/Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; + 0C7F9C9E234CA6AAF7F5EABE /* Pods-TabBarPicker_Example-TabBarPicker-Private.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-TabBarPicker_Example-TabBarPicker-Private.xcconfig"; sourceTree = ""; }; + 0CE25E08DA798F46C5C345BD /* Pods-TabBarPicker_Example-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-TabBarPicker_Example-dummy.m"; sourceTree = ""; }; + 0E0E8BDE68D27DEFCD8D9F6B /* Pods-TabBarPicker_Tests-PureLayout-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-TabBarPicker_Tests-PureLayout-prefix.pch"; sourceTree = ""; }; + 0EAD06508EAD678C349CAA93 /* POPAnimationTracer.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = POPAnimationTracer.mm; path = pop/POPAnimationTracer.mm; sourceTree = ""; }; + 0EE713E3695F83812F704460 /* POPLayerExtras.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = POPLayerExtras.mm; path = pop/POPLayerExtras.mm; sourceTree = ""; }; + 0F8E0704B30253CCB523DFF4 /* Pods-TabBarPicker_Tests-TabBarPicker-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "Pods-TabBarPicker_Tests-TabBarPicker-prefix.pch"; path = "../Pods-TabBarPicker_Tests-TabBarPicker/Pods-TabBarPicker_Tests-TabBarPicker-prefix.pch"; sourceTree = ""; }; + 12300671483B509921D820E8 /* TabBarPicker.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = TabBarPicker.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 1371413CE12B3C17738BA8D2 /* TabBarItem.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = TabBarItem.h; sourceTree = ""; }; + 148DB42881C2CA9E8E5EE6E1 /* TabBarPicker.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = TabBarPicker.h; sourceTree = ""; }; + 161B25D132E8619C8D506575 /* Pods-TabBarPicker_Tests-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-TabBarPicker_Tests-acknowledgements.plist"; sourceTree = ""; }; + 17A33E2AEC69B6B15FC91A29 /* TabBarPicker.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = TabBarPicker.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 17F187FE6CA6214158010BBE /* Pods-TabBarPicker_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-TabBarPicker_Example.release.xcconfig"; sourceTree = ""; }; + 1876E0BBAF9B5083750B89AC /* Pods-TabBarPicker_Example-TabBarPicker.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = "Pods-TabBarPicker_Example-TabBarPicker.modulemap"; sourceTree = ""; }; + 194CECDFA9C949AF055914C0 /* FBSnapshotTestCase.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FBSnapshotTestCase.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 1ED204870830BC4632D23D4D /* Pods-TabBarPicker_Tests-PureLayout.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = "Pods-TabBarPicker_Tests-PureLayout.modulemap"; sourceTree = ""; }; + 1FBA8CEEED1A1191F4961320 /* Pods-TabBarPicker_Example-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-TabBarPicker_Example-acknowledgements.plist"; sourceTree = ""; }; + 1FFBBE368E09DDA2C9F47256 /* POPAnimator.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = POPAnimator.h; path = pop/POPAnimator.h; sourceTree = ""; }; + 2097A7EF439D99B2BE1C3D1C /* Pods-TabBarPicker_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-TabBarPicker_Tests.debug.xcconfig"; sourceTree = ""; }; + 20DAEFB09BBB3604EF2B6FAC /* ALView+PureLayout.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "ALView+PureLayout.m"; path = "PureLayout/PureLayout/ALView+PureLayout.m"; sourceTree = ""; }; + 22F51E2B500C2FF5D08D50C0 /* POPGeometry.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = POPGeometry.mm; path = pop/POPGeometry.mm; sourceTree = ""; }; + 270A861F7A2BE44EAE04DC87 /* Pods_TabBarPicker_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_TabBarPicker_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 271C3F17E60FF4A971EB7D6C /* Pods-TabBarPicker_Example-TabBarPicker-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-TabBarPicker_Example-TabBarPicker-dummy.m"; sourceTree = ""; }; + 2ADB8B46D2F315D0F612EE6D /* TabBarItem.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = TabBarItem.m; sourceTree = ""; }; + 2BA42E3BA28325313FB2B2A3 /* PureLayout+Internal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "PureLayout+Internal.h"; path = "PureLayout/PureLayout/PureLayout+Internal.h"; sourceTree = ""; }; + 2BFE000294D8DE222A710C85 /* Pods-TabBarPicker_Tests-TabBarPicker.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; name = "Pods-TabBarPicker_Tests-TabBarPicker.modulemap"; path = "../Pods-TabBarPicker_Tests-TabBarPicker/Pods-TabBarPicker_Tests-TabBarPicker.modulemap"; sourceTree = ""; }; + 2CE514EAF053F4D716B7AAD9 /* POPAnimationExtras.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = POPAnimationExtras.mm; path = pop/POPAnimationExtras.mm; sourceTree = ""; }; + 2D2A49D478E89B97BAC285F9 /* FBSnapshotTestCasePlatform.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSnapshotTestCasePlatform.m; path = FBSnapshotTestCase/FBSnapshotTestCasePlatform.m; sourceTree = ""; }; + 313943159DCA0E810CAB0726 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 3467B4DD11D47F7D324E3BCC /* FloatConversion.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FloatConversion.h; path = pop/WebCore/FloatConversion.h; sourceTree = ""; }; + 3608461BC17424EEE0E93928 /* Pods-TabBarPicker_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-TabBarPicker_Example.debug.xcconfig"; sourceTree = ""; }; + 37709ECBB155458EFBFFED39 /* UIImage+Compare.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIImage+Compare.h"; path = "FBSnapshotTestCase/UIImage+Compare.h"; sourceTree = ""; }; + 384CEA765776C7069B6E3A0A /* UIImage+Diff.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIImage+Diff.m"; path = "FBSnapshotTestCase/UIImage+Diff.m"; sourceTree = ""; }; + 3C1E962465F636A50709B5CB /* POPAnimationRuntime.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = POPAnimationRuntime.h; path = pop/POPAnimationRuntime.h; sourceTree = ""; }; + 3C33525CA958D87B88D87327 /* Pods-TabBarPicker_Example.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = "Pods-TabBarPicker_Example.modulemap"; sourceTree = ""; }; + 3F75A1B9295C04A7E96EF69E /* POPLayerExtras.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = POPLayerExtras.h; path = pop/POPLayerExtras.h; sourceTree = ""; }; + 3FEB087DA29AB726C4E4DD1E /* Pods-TabBarPicker_Tests-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-TabBarPicker_Tests-dummy.m"; sourceTree = ""; }; + 413FD75D9BC7519CFE72E73B /* POPVector.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = POPVector.h; path = pop/POPVector.h; sourceTree = ""; }; + 428D4B3163A29F10062580F2 /* POPAction.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = POPAction.h; path = pop/POPAction.h; sourceTree = ""; }; + 4393F7BB04FA06DE7A438D20 /* Pods-TabBarPicker_Tests-PureLayout.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-TabBarPicker_Tests-PureLayout.xcconfig"; sourceTree = ""; }; + 4629D4C5444BF9939BD7F95E /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 483BA47373CDB5DCE7469742 /* Pods-TabBarPicker_Tests-TabBarPicker-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "Pods-TabBarPicker_Tests-TabBarPicker-umbrella.h"; path = "../Pods-TabBarPicker_Tests-TabBarPicker/Pods-TabBarPicker_Tests-TabBarPicker-umbrella.h"; sourceTree = ""; }; + 494A2E44D3C1B4593C09F080 /* UIImage+Diff.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "UIImage+Diff.h"; path = "FBSnapshotTestCase/UIImage+Diff.h"; sourceTree = ""; }; + 49EB4C8F7F91F1C7083115B9 /* Pods-TabBarPicker_Tests-FBSnapshotTestCase.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = "Pods-TabBarPicker_Tests-FBSnapshotTestCase.modulemap"; sourceTree = ""; }; + 4A07698F08BB4ED55DF68B7E /* Pods-TabBarPicker_Tests.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = "Pods-TabBarPicker_Tests.modulemap"; sourceTree = ""; }; + 4AC1B5068EBE1625BCF263B5 /* Pods-TabBarPicker_Tests-FBSnapshotTestCase-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-TabBarPicker_Tests-FBSnapshotTestCase-dummy.m"; sourceTree = ""; }; + 4C154F503C254677106143FA /* POPCustomAnimation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = POPCustomAnimation.h; path = pop/POPCustomAnimation.h; sourceTree = ""; }; + 4C6270ED8D95D5EDF4008F37 /* NSArray+PureLayout.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSArray+PureLayout.m"; path = "PureLayout/PureLayout/NSArray+PureLayout.m"; sourceTree = ""; }; + 4F9248C014BA85DA9E62985C /* POPVector.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = POPVector.mm; path = pop/POPVector.mm; sourceTree = ""; }; + 544127507DF529D623BCD492 /* POPSpringAnimation.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = POPSpringAnimation.mm; path = pop/POPSpringAnimation.mm; sourceTree = ""; }; + 565784FDAE1E1414A1BB9D6A /* Pods-TabBarPicker_Tests-FBSnapshotTestCase-Private.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-TabBarPicker_Tests-FBSnapshotTestCase-Private.xcconfig"; sourceTree = ""; }; + 5885BAE70442B3B09EDAA0EE /* POPAnimationEventInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = POPAnimationEventInternal.h; path = pop/POPAnimationEventInternal.h; sourceTree = ""; }; + 5937D50E458DE19FAFF1C2CB /* UnitBezier.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = UnitBezier.h; path = pop/WebCore/UnitBezier.h; sourceTree = ""; }; + 5AD1999225A10120E5B02995 /* Pods-TabBarPicker_Tests-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-TabBarPicker_Tests-umbrella.h"; sourceTree = ""; }; + 60DC3FB0AE4DE499C831C2EF /* PureLayout.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = PureLayout.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 624F4B8D72BCA2E5B0B97961 /* TabBarPicker.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = TabBarPicker.m; sourceTree = ""; }; + 625B087FFE47848ACCB8EE55 /* Pods-TabBarPicker_Example-TabBarPicker-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-TabBarPicker_Example-TabBarPicker-prefix.pch"; sourceTree = ""; }; + 647AEE8412687956E96EC00C /* POPDefines.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = POPDefines.h; path = pop/POPDefines.h; sourceTree = ""; }; + 65A05347063995FDAF01B670 /* POPAnimatableProperty.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = POPAnimatableProperty.mm; path = pop/POPAnimatableProperty.mm; sourceTree = ""; }; + 66133E6E58B8A5577EDE7D48 /* Podfile */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; + 685A2F2C951CB89EDD363751 /* POPBasicAnimation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = POPBasicAnimation.h; path = pop/POPBasicAnimation.h; sourceTree = ""; }; + 697CCDD05A97A526EC9005BA /* Pods-TabBarPicker_Tests-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-TabBarPicker_Tests-acknowledgements.markdown"; sourceTree = ""; }; + 6B80285B23944F6871DB8605 /* POPMath.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = POPMath.mm; path = pop/POPMath.mm; sourceTree = ""; }; + 76BB8DE64767732CFE4A8B40 /* NSLayoutConstraint+PureLayout.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSLayoutConstraint+PureLayout.h"; path = "PureLayout/PureLayout/NSLayoutConstraint+PureLayout.h"; sourceTree = ""; }; + 76CBBC331037069F49A1481B /* Pods-TabBarPicker_Tests-FBSnapshotTestCase-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-TabBarPicker_Tests-FBSnapshotTestCase-umbrella.h"; sourceTree = ""; }; + 7A20EB35B02DAC09E6DB5A03 /* POPSpringSolver.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = POPSpringSolver.h; path = pop/POPSpringSolver.h; sourceTree = ""; }; + 7A5344894FEF98D9616959AF /* POPGeometry.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = POPGeometry.h; path = pop/POPGeometry.h; sourceTree = ""; }; + 7C783CBED75A0003C424981F /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 7CE93A7A2D53987E699A82E0 /* POPAnimation.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = POPAnimation.mm; path = pop/POPAnimation.mm; sourceTree = ""; }; + 824E767F35FFF27587C2FC32 /* Pods-TabBarPicker_Tests-FBSnapshotTestCase.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-TabBarPicker_Tests-FBSnapshotTestCase.xcconfig"; sourceTree = ""; }; + 836C19BF80C4FF0F04846DAE /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS8.3.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; + 85D051E1BBACBD2556FEDC84 /* FBSnapshotTestCase.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSnapshotTestCase.m; path = FBSnapshotTestCase/FBSnapshotTestCase.m; sourceTree = ""; }; + 899203F65224A417FA8DF792 /* POPBasicAnimation.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = POPBasicAnimation.mm; path = pop/POPBasicAnimation.mm; sourceTree = ""; }; + 89A1433A66EAC56F78C55709 /* POPAnimationTracer.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = POPAnimationTracer.h; path = pop/POPAnimationTracer.h; sourceTree = ""; }; + 8C709287CB08F14A495E907E /* POPPropertyAnimation.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = POPPropertyAnimation.mm; path = pop/POPPropertyAnimation.mm; sourceTree = ""; }; + 8CD00ACD98CB3EF2D5A11D2B /* POPAnimationPrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = POPAnimationPrivate.h; path = pop/POPAnimationPrivate.h; sourceTree = ""; }; + 8E8E7A5081A9B7120430EB1C /* TabBarPicker.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TabBarPicker.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + 9332766E99EE0F5D2A1FBA61 /* Pods-TabBarPicker_Tests-TabBarPicker-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "Pods-TabBarPicker_Tests-TabBarPicker-dummy.m"; path = "../Pods-TabBarPicker_Tests-TabBarPicker/Pods-TabBarPicker_Tests-TabBarPicker-dummy.m"; sourceTree = ""; }; + 937BA8EE0828B170DD0E088B /* POPAnimatorPrivate.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = POPAnimatorPrivate.h; path = pop/POPAnimatorPrivate.h; sourceTree = ""; }; + 95ADC5EB5A022DC3684CE488 /* Pods-TabBarPicker_Tests-TabBarPicker.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TabBarPicker_Tests-TabBarPicker.xcconfig"; path = "../Pods-TabBarPicker_Tests-TabBarPicker/Pods-TabBarPicker_Tests-TabBarPicker.xcconfig"; sourceTree = ""; }; + 97AA84C2A069A2176400C2DE /* TabBarSubItem.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = TabBarSubItem.m; sourceTree = ""; }; + 9ACD1B64DC358C440E53AF49 /* Pods-TabBarPicker_Tests-PureLayout-Private.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-TabBarPicker_Tests-PureLayout-Private.xcconfig"; sourceTree = ""; }; + 9C4234366D3D9B62F83646DF /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + A1BC25112DD2DB4E6681FCAF /* POPAnimator.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = POPAnimator.mm; path = pop/POPAnimator.mm; sourceTree = ""; }; + A2E37F810A8B379AF9A5ED62 /* FBSnapshotTestCase.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSnapshotTestCase.h; path = FBSnapshotTestCase/FBSnapshotTestCase.h; sourceTree = ""; }; + A33E846EF6A35C4CEB1811B3 /* POPSpringAnimationInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = POPSpringAnimationInternal.h; path = pop/POPSpringAnimationInternal.h; sourceTree = ""; }; + A79541B5C564B095A7F4DF34 /* POPDecayAnimation.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = POPDecayAnimation.mm; path = pop/POPDecayAnimation.mm; sourceTree = ""; }; + A7B7E6397D072295FE0A5F54 /* NSArray+PureLayout.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSArray+PureLayout.h"; path = "PureLayout/PureLayout/NSArray+PureLayout.h"; sourceTree = ""; }; + AA5C35296813C2034F80213B /* Pods-TabBarPicker_Tests-pop-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-TabBarPicker_Tests-pop-prefix.pch"; sourceTree = ""; }; + ACB75DA6D5B099B35278F7F9 /* Pods-TabBarPicker_Tests-FBSnapshotTestCase-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-TabBarPicker_Tests-FBSnapshotTestCase-prefix.pch"; sourceTree = ""; }; + AD58BB786DB0FA8E5986CF62 /* Pods-TabBarPicker_Example-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-TabBarPicker_Example-umbrella.h"; sourceTree = ""; }; + AD8368EA285B47BC5E4FC67A /* Pods-TabBarPicker_Tests-pop-Private.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-TabBarPicker_Tests-pop-Private.xcconfig"; sourceTree = ""; }; + B247360918A92665C18E2F93 /* POPAnimationInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = POPAnimationInternal.h; path = pop/POPAnimationInternal.h; sourceTree = ""; }; + B507E9F463795031E3CEA800 /* Pods-TabBarPicker_Tests-PureLayout-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-TabBarPicker_Tests-PureLayout-umbrella.h"; sourceTree = ""; }; + B5700F2D4F531E07A88381D3 /* FBSnapshotTestCasePlatform.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSnapshotTestCasePlatform.h; path = FBSnapshotTestCase/FBSnapshotTestCasePlatform.h; sourceTree = ""; }; + B7B0A65C6AFDDBCE9B44D159 /* pop.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = pop.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + B7B8C5A5AD41DCC1AA5383DD /* PureLayoutDefines.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PureLayoutDefines.h; path = PureLayout/PureLayout/PureLayoutDefines.h; sourceTree = ""; }; + B7FEAF540E638E9AEB5DAF2A /* TransformationMatrix.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = TransformationMatrix.h; path = pop/WebCore/TransformationMatrix.h; sourceTree = ""; }; + B822F80A2F008599B37496AF /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + B9F0FDA3FAB24BDE735A32FE /* Pods-TabBarPicker_Example-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-TabBarPicker_Example-frameworks.sh"; sourceTree = ""; }; + BCC83FB56BCBE92BEB16B7A4 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; name = Info.plist; path = "../Pods-TabBarPicker_Tests-TabBarPicker/Info.plist"; sourceTree = ""; }; + BDF1FD88252CA3BCEBBAC8FF /* Pods-TabBarPicker_Tests-pop-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-TabBarPicker_Tests-pop-umbrella.h"; sourceTree = ""; }; + BE648A487E547B56B5FA6092 /* Pods_TabBarPicker_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_TabBarPicker_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + BFC8C255D5605A64BC77DDCE /* POPAnimation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = POPAnimation.h; path = pop/POPAnimation.h; sourceTree = ""; }; + C046D94936BFF08C7EB8A799 /* Pods-TabBarPicker_Tests-pop-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-TabBarPicker_Tests-pop-dummy.m"; sourceTree = ""; }; + C5BBC4E67C2F854A90B1F635 /* ALView+PureLayout.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "ALView+PureLayout.h"; path = "PureLayout/PureLayout/ALView+PureLayout.h"; sourceTree = ""; }; + C6116B0D5A3B5F584BBC044D /* Pods-TabBarPicker_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-TabBarPicker_Tests.release.xcconfig"; sourceTree = ""; }; + CAB8D808D64C356B89F2B4F2 /* UIImage+Compare.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "UIImage+Compare.m"; path = "FBSnapshotTestCase/UIImage+Compare.m"; sourceTree = ""; }; + CADE0F42874C0D1AA6813512 /* Pods-TabBarPicker_Tests-environment.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-TabBarPicker_Tests-environment.h"; sourceTree = ""; }; + D2A821FBF4A3AC98022EE500 /* POPAnimationRuntime.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = POPAnimationRuntime.mm; path = pop/POPAnimationRuntime.mm; sourceTree = ""; }; + D645E5697216C1033B02AFF8 /* TabBarPicker.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TabBarPicker.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + D67D2099C65F165EB6A984A3 /* POPMath.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = POPMath.h; path = pop/POPMath.h; sourceTree = ""; }; + D70593152E0AAA16D569EAA1 /* NSLayoutConstraint+PureLayout.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSLayoutConstraint+PureLayout.m"; path = "PureLayout/PureLayout/NSLayoutConstraint+PureLayout.m"; sourceTree = ""; }; + D72B37CBCBB5AC9907A07492 /* POPCGUtils.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = POPCGUtils.mm; path = pop/POPCGUtils.mm; sourceTree = ""; }; + D80FE7B13075DD9F1A1A659E /* Pods-TabBarPicker_Example-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-TabBarPicker_Example-resources.sh"; sourceTree = ""; }; + D81EB44F93B7D8FCBB471993 /* POPAnimationExtras.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = POPAnimationExtras.h; path = pop/POPAnimationExtras.h; sourceTree = ""; }; + D9AAC91D9567C501A8A72779 /* Pods-TabBarPicker_Tests-pop.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-TabBarPicker_Tests-pop.xcconfig"; sourceTree = ""; }; + D9DED1AB470D76F7CAA0E99B /* POPAnimationEvent.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = POPAnimationEvent.h; path = pop/POPAnimationEvent.h; sourceTree = ""; }; + D9FD69A24E629E9731159547 /* Pods-TabBarPicker_Example-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-TabBarPicker_Example-acknowledgements.markdown"; sourceTree = ""; }; + E03638B659A2C5164CF04D30 /* POPPropertyAnimationInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = POPPropertyAnimationInternal.h; path = pop/POPPropertyAnimationInternal.h; sourceTree = ""; }; + E42D397953D1C3C95F9408EC /* Pods-TabBarPicker_Tests-PureLayout-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-TabBarPicker_Tests-PureLayout-dummy.m"; sourceTree = ""; }; + E4BAA120AA13A1D02FAA23A4 /* Pods-TabBarPicker_Example-TabBarPicker-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-TabBarPicker_Example-TabBarPicker-umbrella.h"; sourceTree = ""; }; + E5D8B474F14DDE4F4D52409E /* POPPropertyAnimation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = POPPropertyAnimation.h; path = pop/POPPropertyAnimation.h; sourceTree = ""; }; + E7E28C15EC58288F48C746F1 /* Pods-TabBarPicker_Tests-TabBarPicker-Private.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TabBarPicker_Tests-TabBarPicker-Private.xcconfig"; path = "../Pods-TabBarPicker_Tests-TabBarPicker/Pods-TabBarPicker_Tests-TabBarPicker-Private.xcconfig"; sourceTree = ""; }; + E900DEC840C6736872C2F7A3 /* POPAnimatableProperty.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = POPAnimatableProperty.h; path = pop/POPAnimatableProperty.h; sourceTree = ""; }; + E952AE82AA42C9BBBE86C72B /* PureLayout.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = PureLayout.h; path = PureLayout/PureLayout/PureLayout.h; sourceTree = ""; }; + EA227E173AB2AE183693AE43 /* POPAnimationTracerInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = POPAnimationTracerInternal.h; path = pop/POPAnimationTracerInternal.h; sourceTree = ""; }; + EE4A88A51750716CC9AB53D9 /* POPCGUtils.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = POPCGUtils.h; path = pop/POPCGUtils.h; sourceTree = ""; }; + EEBDC1DFE7F73BBFA25A3874 /* FBSnapshotTestController.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FBSnapshotTestController.m; path = FBSnapshotTestCase/FBSnapshotTestController.m; sourceTree = ""; }; + EF80A2171E26518439E2FE95 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + F055371F054FE9B88F18F289 /* POPSpringAnimation.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = POPSpringAnimation.h; path = pop/POPSpringAnimation.h; sourceTree = ""; }; + F09E62CF4421B4574210C522 /* FBSnapshotTestController.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FBSnapshotTestController.h; path = FBSnapshotTestCase/FBSnapshotTestController.h; sourceTree = ""; }; + F0CA996C8534E12C67AFFCB4 /* SwiftSupport.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SwiftSupport.swift; path = FBSnapshotTestCase/SwiftSupport.swift; sourceTree = ""; }; + F38CB30BE32060FBD8C51A75 /* TabBarSubItem.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = TabBarSubItem.h; sourceTree = ""; }; + F6F1A79CEC592DA416504BC6 /* Pods-TabBarPicker_Tests-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-TabBarPicker_Tests-resources.sh"; sourceTree = ""; }; + F712C1311B5EE5C36D455BD0 /* TransformationMatrix.cpp */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.cpp; name = TransformationMatrix.cpp; path = pop/WebCore/TransformationMatrix.cpp; sourceTree = ""; }; + F81EB2A3140776A97E772415 /* Pods-TabBarPicker_Example-environment.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-TabBarPicker_Example-environment.h"; sourceTree = ""; }; + F8F7F7A98DB8365AB6F2CE16 /* Pods-TabBarPicker_Tests-pop.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = "Pods-TabBarPicker_Tests-pop.modulemap"; sourceTree = ""; }; + F9272C6C8510653C958CE89A /* POPAnimationEvent.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = POPAnimationEvent.mm; path = pop/POPAnimationEvent.mm; sourceTree = ""; }; + FA8D04C3ECD5B2B3C79AF0FD /* POPCustomAnimation.mm */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.cpp.objcpp; name = POPCustomAnimation.mm; path = pop/POPCustomAnimation.mm; sourceTree = ""; }; + FC2BA9782BDD678A4FCAF56E /* Pods-TabBarPicker_Example-TabBarPicker.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-TabBarPicker_Example-TabBarPicker.xcconfig"; sourceTree = ""; }; + FD6E18FA54DF8FB7CF9BCE73 /* POPDecayAnimationInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = POPDecayAnimationInternal.h; path = pop/POPDecayAnimationInternal.h; sourceTree = ""; }; + FFCA0749279D282CA89A3BBB /* POPBasicAnimationInternal.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = POPBasicAnimationInternal.h; path = pop/POPBasicAnimationInternal.h; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 1D464096B0A2D21F8A1DD8BC /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 9647BD594D454AA36B317BCA /* Foundation.framework in Frameworks */, + C108F31F0426C3C4141B2A3A /* XCTest.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 25A9733B9CFD86B0B9C49FBB /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 912985F63EFD09B575DF6149 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 4D7AA1B2CA10A369CC3E7B47 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 85C9FF86C8C7E0EC83C0B974 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + F66B3044416BCD206343E08A /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A1B82488D27970757F1D39B1 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 45625B69AC49546CDDF3354E /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A62B044A344674144742B21F /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + D4D8565B5B52B5E6C0D1E23E /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B0370C6D90D456531F5F6F7B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D44EE62EA83C8C9C25C6399B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 69EF0AF9146AABC83DD15197 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + FB037F553812273A6399BD13 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + CDC7C637CE560B20F11D500B /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 01F3BF7BC7DD474B94707B54 /* Classes */ = { + isa = PBXGroup; + children = ( + 1371413CE12B3C17738BA8D2 /* TabBarItem.h */, + 2ADB8B46D2F315D0F612EE6D /* TabBarItem.m */, + 148DB42881C2CA9E8E5EE6E1 /* TabBarPicker.h */, + 624F4B8D72BCA2E5B0B97961 /* TabBarPicker.m */, + F38CB30BE32060FBD8C51A75 /* TabBarSubItem.h */, + 97AA84C2A069A2176400C2DE /* TabBarSubItem.m */, + ); + path = Classes; + sourceTree = ""; + }; + 0205E7CAF4A61F37B52562E2 /* SwiftSupport */ = { + isa = PBXGroup; + children = ( + F0CA996C8534E12C67AFFCB4 /* SwiftSupport.swift */, + ); + name = SwiftSupport; + sourceTree = ""; + }; + 0385D20860AF501CBBC0AA7B /* Pods-TabBarPicker_Example */ = { + isa = PBXGroup; + children = ( + 7C783CBED75A0003C424981F /* Info.plist */, + 3C33525CA958D87B88D87327 /* Pods-TabBarPicker_Example.modulemap */, + D9FD69A24E629E9731159547 /* Pods-TabBarPicker_Example-acknowledgements.markdown */, + 1FBA8CEEED1A1191F4961320 /* Pods-TabBarPicker_Example-acknowledgements.plist */, + 0CE25E08DA798F46C5C345BD /* Pods-TabBarPicker_Example-dummy.m */, + F81EB2A3140776A97E772415 /* Pods-TabBarPicker_Example-environment.h */, + B9F0FDA3FAB24BDE735A32FE /* Pods-TabBarPicker_Example-frameworks.sh */, + D80FE7B13075DD9F1A1A659E /* Pods-TabBarPicker_Example-resources.sh */, + AD58BB786DB0FA8E5986CF62 /* Pods-TabBarPicker_Example-umbrella.h */, + 3608461BC17424EEE0E93928 /* Pods-TabBarPicker_Example.debug.xcconfig */, + 17F187FE6CA6214158010BBE /* Pods-TabBarPicker_Example.release.xcconfig */, + ); + name = "Pods-TabBarPicker_Example"; + path = "Target Support Files/Pods-TabBarPicker_Example"; + sourceTree = ""; + }; + 218C143A3163FA8EDC1EE306 /* iOS */ = { + isa = PBXGroup; + children = ( + 836C19BF80C4FF0F04846DAE /* Foundation.framework */, + 0A709C0164EDF439E429804C /* XCTest.framework */, + ); + name = iOS; + sourceTree = ""; + }; + 397FCCCB6925294507E12DB4 /* Pods-TabBarPicker_Tests */ = { + isa = PBXGroup; + children = ( + 4629D4C5444BF9939BD7F95E /* Info.plist */, + 4A07698F08BB4ED55DF68B7E /* Pods-TabBarPicker_Tests.modulemap */, + 697CCDD05A97A526EC9005BA /* Pods-TabBarPicker_Tests-acknowledgements.markdown */, + 161B25D132E8619C8D506575 /* Pods-TabBarPicker_Tests-acknowledgements.plist */, + 3FEB087DA29AB726C4E4DD1E /* Pods-TabBarPicker_Tests-dummy.m */, + CADE0F42874C0D1AA6813512 /* Pods-TabBarPicker_Tests-environment.h */, + 032060E06DB91F8976AB60CF /* Pods-TabBarPicker_Tests-frameworks.sh */, + F6F1A79CEC592DA416504BC6 /* Pods-TabBarPicker_Tests-resources.sh */, + 5AD1999225A10120E5B02995 /* Pods-TabBarPicker_Tests-umbrella.h */, + 2097A7EF439D99B2BE1C3D1C /* Pods-TabBarPicker_Tests.debug.xcconfig */, + C6116B0D5A3B5F584BBC044D /* Pods-TabBarPicker_Tests.release.xcconfig */, + ); + name = "Pods-TabBarPicker_Tests"; + path = "Target Support Files/Pods-TabBarPicker_Tests"; + sourceTree = ""; + }; + 4AD6C808057F1BE0276F747D = { + isa = PBXGroup; + children = ( + 66133E6E58B8A5577EDE7D48 /* Podfile */, + 99707A55F723E8B66BFE9BF3 /* Development Pods */, + D93D22476D14850AAD02077A /* Frameworks */, + 8D3D7A55D8BD002686107DC9 /* Pods */, + B4203E66B10EC56449A50D56 /* Products */, + 8383C26D7994F98614FBD4C1 /* Targets Support Files */, + ); + sourceTree = ""; + }; + 8383C26D7994F98614FBD4C1 /* Targets Support Files */ = { + isa = PBXGroup; + children = ( + 0385D20860AF501CBBC0AA7B /* Pods-TabBarPicker_Example */, + 397FCCCB6925294507E12DB4 /* Pods-TabBarPicker_Tests */, + ); + name = "Targets Support Files"; + sourceTree = ""; + }; + 8CF4A5196671D817A4BDE283 /* Support Files */ = { + isa = PBXGroup; + children = ( + B822F80A2F008599B37496AF /* Info.plist */, + 1ED204870830BC4632D23D4D /* Pods-TabBarPicker_Tests-PureLayout.modulemap */, + 4393F7BB04FA06DE7A438D20 /* Pods-TabBarPicker_Tests-PureLayout.xcconfig */, + 9ACD1B64DC358C440E53AF49 /* Pods-TabBarPicker_Tests-PureLayout-Private.xcconfig */, + E42D397953D1C3C95F9408EC /* Pods-TabBarPicker_Tests-PureLayout-dummy.m */, + 0E0E8BDE68D27DEFCD8D9F6B /* Pods-TabBarPicker_Tests-PureLayout-prefix.pch */, + B507E9F463795031E3CEA800 /* Pods-TabBarPicker_Tests-PureLayout-umbrella.h */, + ); + name = "Support Files"; + path = "../Target Support Files/Pods-TabBarPicker_Tests-PureLayout"; + sourceTree = ""; + }; + 8D3D7A55D8BD002686107DC9 /* Pods */ = { + isa = PBXGroup; + children = ( + AF192C6DE1F84C1874CDCC57 /* FBSnapshotTestCase */, + F19EC70F0AB3444190CC7A52 /* PureLayout */, + B585245BE73FECCC9755DC09 /* pop */, + ); + name = Pods; + sourceTree = ""; + }; + 99707A55F723E8B66BFE9BF3 /* Development Pods */ = { + isa = PBXGroup; + children = ( + A2A9ABF63E2A0DA6ED9A8D04 /* TabBarPicker */, + ); + name = "Development Pods"; + sourceTree = ""; + }; + A2A9ABF63E2A0DA6ED9A8D04 /* TabBarPicker */ = { + isa = PBXGroup; + children = ( + EEBBC423387915EF18233718 /* Pod */, + CF3D20C822A1D9F69E628C0C /* Support Files */, + ); + name = TabBarPicker; + path = ../..; + sourceTree = ""; + }; + AF192C6DE1F84C1874CDCC57 /* FBSnapshotTestCase */ = { + isa = PBXGroup; + children = ( + BCED8B602F7C202CDABFF944 /* Core */, + FBB7136015A603F89C430027 /* Support Files */, + 0205E7CAF4A61F37B52562E2 /* SwiftSupport */, + ); + path = FBSnapshotTestCase; + sourceTree = ""; + }; + B4203E66B10EC56449A50D56 /* Products */ = { + isa = PBXGroup; + children = ( + 194CECDFA9C949AF055914C0 /* FBSnapshotTestCase.framework */, + 270A861F7A2BE44EAE04DC87 /* Pods_TabBarPicker_Example.framework */, + BE648A487E547B56B5FA6092 /* Pods_TabBarPicker_Tests.framework */, + 60DC3FB0AE4DE499C831C2EF /* PureLayout.framework */, + D645E5697216C1033B02AFF8 /* TabBarPicker.bundle */, + 8E8E7A5081A9B7120430EB1C /* TabBarPicker.bundle */, + 12300671483B509921D820E8 /* TabBarPicker.framework */, + 17A33E2AEC69B6B15FC91A29 /* TabBarPicker.framework */, + B7B0A65C6AFDDBCE9B44D159 /* pop.framework */, + ); + name = Products; + sourceTree = ""; + }; + B585245BE73FECCC9755DC09 /* pop */ = { + isa = PBXGroup; + children = ( + 3467B4DD11D47F7D324E3BCC /* FloatConversion.h */, + 02A5AABEEC9D765E78544C8A /* POP.h */, + 428D4B3163A29F10062580F2 /* POPAction.h */, + E900DEC840C6736872C2F7A3 /* POPAnimatableProperty.h */, + 65A05347063995FDAF01B670 /* POPAnimatableProperty.mm */, + BFC8C255D5605A64BC77DDCE /* POPAnimation.h */, + 7CE93A7A2D53987E699A82E0 /* POPAnimation.mm */, + D9DED1AB470D76F7CAA0E99B /* POPAnimationEvent.h */, + F9272C6C8510653C958CE89A /* POPAnimationEvent.mm */, + 5885BAE70442B3B09EDAA0EE /* POPAnimationEventInternal.h */, + D81EB44F93B7D8FCBB471993 /* POPAnimationExtras.h */, + 2CE514EAF053F4D716B7AAD9 /* POPAnimationExtras.mm */, + B247360918A92665C18E2F93 /* POPAnimationInternal.h */, + 8CD00ACD98CB3EF2D5A11D2B /* POPAnimationPrivate.h */, + 3C1E962465F636A50709B5CB /* POPAnimationRuntime.h */, + D2A821FBF4A3AC98022EE500 /* POPAnimationRuntime.mm */, + 89A1433A66EAC56F78C55709 /* POPAnimationTracer.h */, + 0EAD06508EAD678C349CAA93 /* POPAnimationTracer.mm */, + EA227E173AB2AE183693AE43 /* POPAnimationTracerInternal.h */, + 1FFBBE368E09DDA2C9F47256 /* POPAnimator.h */, + A1BC25112DD2DB4E6681FCAF /* POPAnimator.mm */, + 937BA8EE0828B170DD0E088B /* POPAnimatorPrivate.h */, + 685A2F2C951CB89EDD363751 /* POPBasicAnimation.h */, + 899203F65224A417FA8DF792 /* POPBasicAnimation.mm */, + FFCA0749279D282CA89A3BBB /* POPBasicAnimationInternal.h */, + EE4A88A51750716CC9AB53D9 /* POPCGUtils.h */, + D72B37CBCBB5AC9907A07492 /* POPCGUtils.mm */, + 4C154F503C254677106143FA /* POPCustomAnimation.h */, + FA8D04C3ECD5B2B3C79AF0FD /* POPCustomAnimation.mm */, + 0621F69BD40BD272EB5A92E6 /* POPDecayAnimation.h */, + A79541B5C564B095A7F4DF34 /* POPDecayAnimation.mm */, + FD6E18FA54DF8FB7CF9BCE73 /* POPDecayAnimationInternal.h */, + 647AEE8412687956E96EC00C /* POPDefines.h */, + 7A5344894FEF98D9616959AF /* POPGeometry.h */, + 22F51E2B500C2FF5D08D50C0 /* POPGeometry.mm */, + 3F75A1B9295C04A7E96EF69E /* POPLayerExtras.h */, + 0EE713E3695F83812F704460 /* POPLayerExtras.mm */, + D67D2099C65F165EB6A984A3 /* POPMath.h */, + 6B80285B23944F6871DB8605 /* POPMath.mm */, + E5D8B474F14DDE4F4D52409E /* POPPropertyAnimation.h */, + 8C709287CB08F14A495E907E /* POPPropertyAnimation.mm */, + E03638B659A2C5164CF04D30 /* POPPropertyAnimationInternal.h */, + F055371F054FE9B88F18F289 /* POPSpringAnimation.h */, + 544127507DF529D623BCD492 /* POPSpringAnimation.mm */, + A33E846EF6A35C4CEB1811B3 /* POPSpringAnimationInternal.h */, + 7A20EB35B02DAC09E6DB5A03 /* POPSpringSolver.h */, + 413FD75D9BC7519CFE72E73B /* POPVector.h */, + 4F9248C014BA85DA9E62985C /* POPVector.mm */, + F712C1311B5EE5C36D455BD0 /* TransformationMatrix.cpp */, + B7FEAF540E638E9AEB5DAF2A /* TransformationMatrix.h */, + 5937D50E458DE19FAFF1C2CB /* UnitBezier.h */, + CE04CBEBC849953A8BBF6D6D /* Support Files */, + ); + path = pop; + sourceTree = ""; + }; + BCED8B602F7C202CDABFF944 /* Core */ = { + isa = PBXGroup; + children = ( + A2E37F810A8B379AF9A5ED62 /* FBSnapshotTestCase.h */, + 85D051E1BBACBD2556FEDC84 /* FBSnapshotTestCase.m */, + B5700F2D4F531E07A88381D3 /* FBSnapshotTestCasePlatform.h */, + 2D2A49D478E89B97BAC285F9 /* FBSnapshotTestCasePlatform.m */, + F09E62CF4421B4574210C522 /* FBSnapshotTestController.h */, + EEBDC1DFE7F73BBFA25A3874 /* FBSnapshotTestController.m */, + 37709ECBB155458EFBFFED39 /* UIImage+Compare.h */, + CAB8D808D64C356B89F2B4F2 /* UIImage+Compare.m */, + 494A2E44D3C1B4593C09F080 /* UIImage+Diff.h */, + 384CEA765776C7069B6E3A0A /* UIImage+Diff.m */, + ); + name = Core; + sourceTree = ""; + }; + CE04CBEBC849953A8BBF6D6D /* Support Files */ = { + isa = PBXGroup; + children = ( + 9C4234366D3D9B62F83646DF /* Info.plist */, + F8F7F7A98DB8365AB6F2CE16 /* Pods-TabBarPicker_Tests-pop.modulemap */, + D9AAC91D9567C501A8A72779 /* Pods-TabBarPicker_Tests-pop.xcconfig */, + AD8368EA285B47BC5E4FC67A /* Pods-TabBarPicker_Tests-pop-Private.xcconfig */, + C046D94936BFF08C7EB8A799 /* Pods-TabBarPicker_Tests-pop-dummy.m */, + AA5C35296813C2034F80213B /* Pods-TabBarPicker_Tests-pop-prefix.pch */, + BDF1FD88252CA3BCEBBAC8FF /* Pods-TabBarPicker_Tests-pop-umbrella.h */, + ); + name = "Support Files"; + path = "../Target Support Files/Pods-TabBarPicker_Tests-pop"; + sourceTree = ""; + }; + CF3D20C822A1D9F69E628C0C /* Support Files */ = { + isa = PBXGroup; + children = ( + EF80A2171E26518439E2FE95 /* Info.plist */, + BCC83FB56BCBE92BEB16B7A4 /* Info.plist */, + 1876E0BBAF9B5083750B89AC /* Pods-TabBarPicker_Example-TabBarPicker.modulemap */, + FC2BA9782BDD678A4FCAF56E /* Pods-TabBarPicker_Example-TabBarPicker.xcconfig */, + 0C7F9C9E234CA6AAF7F5EABE /* Pods-TabBarPicker_Example-TabBarPicker-Private.xcconfig */, + 271C3F17E60FF4A971EB7D6C /* Pods-TabBarPicker_Example-TabBarPicker-dummy.m */, + 625B087FFE47848ACCB8EE55 /* Pods-TabBarPicker_Example-TabBarPicker-prefix.pch */, + E4BAA120AA13A1D02FAA23A4 /* Pods-TabBarPicker_Example-TabBarPicker-umbrella.h */, + 2BFE000294D8DE222A710C85 /* Pods-TabBarPicker_Tests-TabBarPicker.modulemap */, + 95ADC5EB5A022DC3684CE488 /* Pods-TabBarPicker_Tests-TabBarPicker.xcconfig */, + E7E28C15EC58288F48C746F1 /* Pods-TabBarPicker_Tests-TabBarPicker-Private.xcconfig */, + 9332766E99EE0F5D2A1FBA61 /* Pods-TabBarPicker_Tests-TabBarPicker-dummy.m */, + 0F8E0704B30253CCB523DFF4 /* Pods-TabBarPicker_Tests-TabBarPicker-prefix.pch */, + 483BA47373CDB5DCE7469742 /* Pods-TabBarPicker_Tests-TabBarPicker-umbrella.h */, + ); + name = "Support Files"; + path = "Example/Pods/Target Support Files/Pods-TabBarPicker_Example-TabBarPicker"; + sourceTree = ""; + }; + D93D22476D14850AAD02077A /* Frameworks */ = { + isa = PBXGroup; + children = ( + 218C143A3163FA8EDC1EE306 /* iOS */, + ); + name = Frameworks; + sourceTree = ""; + }; + EEBBC423387915EF18233718 /* Pod */ = { + isa = PBXGroup; + children = ( + 01F3BF7BC7DD474B94707B54 /* Classes */, + ); + path = Pod; + sourceTree = ""; + }; + F19EC70F0AB3444190CC7A52 /* PureLayout */ = { + isa = PBXGroup; + children = ( + C5BBC4E67C2F854A90B1F635 /* ALView+PureLayout.h */, + 20DAEFB09BBB3604EF2B6FAC /* ALView+PureLayout.m */, + A7B7E6397D072295FE0A5F54 /* NSArray+PureLayout.h */, + 4C6270ED8D95D5EDF4008F37 /* NSArray+PureLayout.m */, + 76BB8DE64767732CFE4A8B40 /* NSLayoutConstraint+PureLayout.h */, + D70593152E0AAA16D569EAA1 /* NSLayoutConstraint+PureLayout.m */, + E952AE82AA42C9BBBE86C72B /* PureLayout.h */, + 2BA42E3BA28325313FB2B2A3 /* PureLayout+Internal.h */, + B7B8C5A5AD41DCC1AA5383DD /* PureLayoutDefines.h */, + 8CF4A5196671D817A4BDE283 /* Support Files */, + ); + path = PureLayout; + sourceTree = ""; + }; + FBB7136015A603F89C430027 /* Support Files */ = { + isa = PBXGroup; + children = ( + 313943159DCA0E810CAB0726 /* Info.plist */, + 49EB4C8F7F91F1C7083115B9 /* Pods-TabBarPicker_Tests-FBSnapshotTestCase.modulemap */, + 824E767F35FFF27587C2FC32 /* Pods-TabBarPicker_Tests-FBSnapshotTestCase.xcconfig */, + 565784FDAE1E1414A1BB9D6A /* Pods-TabBarPicker_Tests-FBSnapshotTestCase-Private.xcconfig */, + 4AC1B5068EBE1625BCF263B5 /* Pods-TabBarPicker_Tests-FBSnapshotTestCase-dummy.m */, + ACB75DA6D5B099B35278F7F9 /* Pods-TabBarPicker_Tests-FBSnapshotTestCase-prefix.pch */, + 76CBBC331037069F49A1481B /* Pods-TabBarPicker_Tests-FBSnapshotTestCase-umbrella.h */, + ); + name = "Support Files"; + path = "../Target Support Files/Pods-TabBarPicker_Tests-FBSnapshotTestCase"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 1B323BB02900DB0CCDBE6E42 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 6223D7701E616A12B9886220 /* Pods-TabBarPicker_Tests-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 3B54E464D4B6DC5BC368D120 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 6E93B61EB2DEDE0964E3B1EE /* Pods-TabBarPicker_Tests-TabBarPicker-umbrella.h in Headers */, + BEE9747F66B393FEEFE81E35 /* TabBarItem.h in Headers */, + 124D751F1A50BADA38571F52 /* TabBarPicker.h in Headers */, + 27A0DF5F969CB972F019D658 /* TabBarSubItem.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 578793AF03626DCCBA89F4D4 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 7A23C9B612EBF9AD343CE1E2 /* FloatConversion.h in Headers */, + 90FCFA53B151BE9EFDCB409B /* POP.h in Headers */, + 7247D3BD1744F25683AD5F8D /* POPAction.h in Headers */, + 53160D4212932FC7C56D3EF2 /* POPAnimatableProperty.h in Headers */, + 09A4D4FD25C7CF71000BFD2F /* POPAnimation.h in Headers */, + 55D74730D1FB242A78A3C0E2 /* POPAnimationEvent.h in Headers */, + 108142577EB2C6F99ADA8C61 /* POPAnimationEventInternal.h in Headers */, + 7E2F911B68DDD100F76D2D90 /* POPAnimationExtras.h in Headers */, + 3BD54709283F3AACAABAEF9B /* POPAnimationInternal.h in Headers */, + 3EE6AB8DD62DB60E64D05A0C /* POPAnimationPrivate.h in Headers */, + 33C553DA18FDC7D9B3978AB1 /* POPAnimationRuntime.h in Headers */, + 5D73A845AC7211A277B2B3B4 /* POPAnimationTracer.h in Headers */, + 5A94D7E53BF242DED78CFAA0 /* POPAnimationTracerInternal.h in Headers */, + 7EEFD4EEF35DCB13D8049996 /* POPAnimator.h in Headers */, + 65B31B3C4504F32874FBFD98 /* POPAnimatorPrivate.h in Headers */, + 10CD87106DC803FFAE595FF3 /* POPBasicAnimation.h in Headers */, + D87F6826919FDDA6D85A58A7 /* POPBasicAnimationInternal.h in Headers */, + 6C7DD001B76A2341D3B3516A /* POPCGUtils.h in Headers */, + 4F168F8645C1E934DD6F1BC2 /* POPCustomAnimation.h in Headers */, + 6636FFF6FFBCCE668F3E9F87 /* POPDecayAnimation.h in Headers */, + 77ADA9D3C1DB1B0AEDFF1113 /* POPDecayAnimationInternal.h in Headers */, + D9249B401EAFBC7E735A59E1 /* POPDefines.h in Headers */, + 14F43215C15DD385DC37FCC7 /* POPGeometry.h in Headers */, + C4A5D52AB2139FA5A09919D9 /* POPLayerExtras.h in Headers */, + 519595A4F772637BFA8F84B7 /* POPMath.h in Headers */, + 58202E9C720A5DA7AC69572C /* POPPropertyAnimation.h in Headers */, + 162BEA745AAA759206480273 /* POPPropertyAnimationInternal.h in Headers */, + B858BAD455D0DB8F907F3128 /* POPSpringAnimation.h in Headers */, + 58F869B2B16B8D3A5BE0A964 /* POPSpringAnimationInternal.h in Headers */, + C230EF663C8B2E9AA75BB7C7 /* POPSpringSolver.h in Headers */, + 2E5474CD0D2321F240A9DFE8 /* POPVector.h in Headers */, + 2116A6EA200DC1D2328AB03A /* Pods-TabBarPicker_Tests-pop-umbrella.h in Headers */, + 0E6A3ED7F51A2B603FC8AA84 /* TransformationMatrix.h in Headers */, + 6629264412C2FE52A1169348 /* UnitBezier.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 89D8DC3D35AADFF53874867C /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + A8ABDEDC714A994B6B36A4F1 /* Pods-TabBarPicker_Example-TabBarPicker-umbrella.h in Headers */, + C591C499E7FB0CF3D776512B /* TabBarItem.h in Headers */, + 5C89C0AA72C233E829573398 /* TabBarPicker.h in Headers */, + D15A957FA849695B2BC0E2BA /* TabBarSubItem.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9B1BA7A312C625E213812DA9 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 2DB8E0125011E2555B599F6F /* FBSnapshotTestCase.h in Headers */, + 777C0B3EE3BF68B1B878885A /* FBSnapshotTestCasePlatform.h in Headers */, + D3052435A90B887C4E7AEAC0 /* FBSnapshotTestController.h in Headers */, + 58C14E475C19C9C5F963EBAF /* Pods-TabBarPicker_Tests-FBSnapshotTestCase-umbrella.h in Headers */, + FD8BF6D2DA1679CE61A6F527 /* UIImage+Compare.h in Headers */, + B1514CE9C56F3D9A14947483 /* UIImage+Diff.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B43C65B92CC71DAE463BC8C9 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + E171CC4952BB865125F56FC4 /* ALView+PureLayout.h in Headers */, + 62E823E5143EB6A31CA83F64 /* NSArray+PureLayout.h in Headers */, + 24ABCA32BE6380A98CF98E28 /* NSLayoutConstraint+PureLayout.h in Headers */, + 16D4A319EB5B6BA724F18A14 /* Pods-TabBarPicker_Tests-PureLayout-umbrella.h in Headers */, + 0F8A059B32D797853970DD24 /* PureLayout+Internal.h in Headers */, + 1E8C432521038851EDD5B9F3 /* PureLayout.h in Headers */, + D4B8AA680BDB18DE67139A6C /* PureLayoutDefines.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + C13AB0E855B793946C22A902 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + D32535025C6A0066C7FDF4C7 /* Pods-TabBarPicker_Example-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 25EC7DE4FAEEEF84395686BD /* Pods-TabBarPicker_Tests-FBSnapshotTestCase */ = { + isa = PBXNativeTarget; + buildConfigurationList = 9AE8E44F818B51C74314F350 /* Build configuration list for PBXNativeTarget "Pods-TabBarPicker_Tests-FBSnapshotTestCase" */; + buildPhases = ( + 224D255F6619A9EE8DCF1F89 /* Sources */, + 1D464096B0A2D21F8A1DD8BC /* Frameworks */, + 9B1BA7A312C625E213812DA9 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "Pods-TabBarPicker_Tests-FBSnapshotTestCase"; + productName = "Pods-TabBarPicker_Tests-FBSnapshotTestCase"; + productReference = 194CECDFA9C949AF055914C0 /* FBSnapshotTestCase.framework */; + productType = "com.apple.product-type.framework"; + }; + 3998475720C1C47684180202 /* Pods-TabBarPicker_Tests-PureLayout */ = { + isa = PBXNativeTarget; + buildConfigurationList = E2A01AEE9484A7CAC7FAF8E1 /* Build configuration list for PBXNativeTarget "Pods-TabBarPicker_Tests-PureLayout" */; + buildPhases = ( + E7F14378429DFFCE7EFFEC2A /* Sources */, + A1B82488D27970757F1D39B1 /* Frameworks */, + B43C65B92CC71DAE463BC8C9 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "Pods-TabBarPicker_Tests-PureLayout"; + productName = "Pods-TabBarPicker_Tests-PureLayout"; + productReference = 60DC3FB0AE4DE499C831C2EF /* PureLayout.framework */; + productType = "com.apple.product-type.framework"; + }; + 561939E4515B71341136E16E /* Pods-TabBarPicker_Tests-TabBarPicker */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1249393950AA2AFADACAB1CB /* Build configuration list for PBXNativeTarget "Pods-TabBarPicker_Tests-TabBarPicker" */; + buildPhases = ( + D3436181D8E54050939D3076 /* Sources */, + D44EE62EA83C8C9C25C6399B /* Frameworks */, + 3C6C6E272796555543FDDD24 /* Resources */, + 3B54E464D4B6DC5BC368D120 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + 3D385874E49584FB68248735 /* PBXTargetDependency */, + ); + name = "Pods-TabBarPicker_Tests-TabBarPicker"; + productName = "Pods-TabBarPicker_Tests-TabBarPicker"; + productReference = 12300671483B509921D820E8 /* TabBarPicker.framework */; + productType = "com.apple.product-type.framework"; + }; + 7FBA3465F9826D032614FF28 /* Pods-TabBarPicker_Example */ = { + isa = PBXNativeTarget; + buildConfigurationList = 8CE83C4A2D070D01A02146BC /* Build configuration list for PBXNativeTarget "Pods-TabBarPicker_Example" */; + buildPhases = ( + BD5F548A0F7E932A81CF6FA0 /* Sources */, + A62B044A344674144742B21F /* Frameworks */, + C13AB0E855B793946C22A902 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + 6681ABC2479B156BD4E4281B /* PBXTargetDependency */, + ); + name = "Pods-TabBarPicker_Example"; + productName = "Pods-TabBarPicker_Example"; + productReference = 270A861F7A2BE44EAE04DC87 /* Pods_TabBarPicker_Example.framework */; + productType = "com.apple.product-type.framework"; + }; + 8CA46A24F79F8A2591154DC8 /* Pods-TabBarPicker_Example-TabBarPicker-TabBarPicker */ = { + isa = PBXNativeTarget; + buildConfigurationList = 47ACCA4578EB0CE15C6A5317 /* Build configuration list for PBXNativeTarget "Pods-TabBarPicker_Example-TabBarPicker-TabBarPicker" */; + buildPhases = ( + 8BE095C921BE6BA584278DF1 /* Sources */, + 4D7AA1B2CA10A369CC3E7B47 /* Frameworks */, + 901FC6E11A04D8CA4B1F8CE2 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "Pods-TabBarPicker_Example-TabBarPicker-TabBarPicker"; + productName = "Pods-TabBarPicker_Example-TabBarPicker-TabBarPicker"; + productReference = 8E8E7A5081A9B7120430EB1C /* TabBarPicker.bundle */; + productType = "com.apple.product-type.bundle"; + }; + AE841CD8269D52D367EBAEBB /* Pods-TabBarPicker_Example-TabBarPicker */ = { + isa = PBXNativeTarget; + buildConfigurationList = ADA31270D06F7C2E2E1867DA /* Build configuration list for PBXNativeTarget "Pods-TabBarPicker_Example-TabBarPicker" */; + buildPhases = ( + CCE054CBAA7C18EC4190E6A8 /* Sources */, + 85C9FF86C8C7E0EC83C0B974 /* Frameworks */, + BC59ECA047DB5F78B01D591A /* Resources */, + 89D8DC3D35AADFF53874867C /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + 513C7CB9E2AD5FFFACAF085A /* PBXTargetDependency */, + ); + name = "Pods-TabBarPicker_Example-TabBarPicker"; + productName = "Pods-TabBarPicker_Example-TabBarPicker"; + productReference = 17A33E2AEC69B6B15FC91A29 /* TabBarPicker.framework */; + productType = "com.apple.product-type.framework"; + }; + C26F15991223F90FD04DB84A /* Pods-TabBarPicker_Tests-TabBarPicker-TabBarPicker */ = { + isa = PBXNativeTarget; + buildConfigurationList = 27426159E1BA8D677C1F5403 /* Build configuration list for PBXNativeTarget "Pods-TabBarPicker_Tests-TabBarPicker-TabBarPicker" */; + buildPhases = ( + 7981162BCF60CBF79B62F96A /* Sources */, + B0370C6D90D456531F5F6F7B /* Frameworks */, + 57DD5422982ACFD674C97697 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "Pods-TabBarPicker_Tests-TabBarPicker-TabBarPicker"; + productName = "Pods-TabBarPicker_Tests-TabBarPicker-TabBarPicker"; + productReference = D645E5697216C1033B02AFF8 /* TabBarPicker.bundle */; + productType = "com.apple.product-type.bundle"; + }; + CF3DCEB04961FDED1CAC4B7D /* Pods-TabBarPicker_Tests-pop */ = { + isa = PBXNativeTarget; + buildConfigurationList = E923A51F7294D674E9BAB4F1 /* Build configuration list for PBXNativeTarget "Pods-TabBarPicker_Tests-pop" */; + buildPhases = ( + BB436824BBE685CB4A77D692 /* Sources */, + FB037F553812273A6399BD13 /* Frameworks */, + 578793AF03626DCCBA89F4D4 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "Pods-TabBarPicker_Tests-pop"; + productName = "Pods-TabBarPicker_Tests-pop"; + productReference = B7B0A65C6AFDDBCE9B44D159 /* pop.framework */; + productType = "com.apple.product-type.framework"; + }; + DBB89396FBAFD709790F301A /* Pods-TabBarPicker_Tests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 67F910D5E6FB101761D3287A /* Build configuration list for PBXNativeTarget "Pods-TabBarPicker_Tests" */; + buildPhases = ( + 90800D06757C741CF1EA45A3 /* Sources */, + 25A9733B9CFD86B0B9C49FBB /* Frameworks */, + 1B323BB02900DB0CCDBE6E42 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + F9B7ECEE3092959AD130ECE4 /* PBXTargetDependency */, + 2D1FCBF0F71D941BDE18AB4C /* PBXTargetDependency */, + 846F0B626200761F44F71507 /* PBXTargetDependency */, + C0DB0110D32ECDDB0A4AD0AB /* PBXTargetDependency */, + ); + name = "Pods-TabBarPicker_Tests"; + productName = "Pods-TabBarPicker_Tests"; + productReference = BE648A487E547B56B5FA6092 /* Pods_TabBarPicker_Tests.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + D9442BE4A2137345B01F164F /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0640; + }; + buildConfigurationList = A9984B49EB9549F746394505 /* Build configuration list for PBXProject "Pods" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 4AD6C808057F1BE0276F747D; + productRefGroup = B4203E66B10EC56449A50D56 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 7FBA3465F9826D032614FF28 /* Pods-TabBarPicker_Example */, + AE841CD8269D52D367EBAEBB /* Pods-TabBarPicker_Example-TabBarPicker */, + 8CA46A24F79F8A2591154DC8 /* Pods-TabBarPicker_Example-TabBarPicker-TabBarPicker */, + DBB89396FBAFD709790F301A /* Pods-TabBarPicker_Tests */, + 25EC7DE4FAEEEF84395686BD /* Pods-TabBarPicker_Tests-FBSnapshotTestCase */, + 3998475720C1C47684180202 /* Pods-TabBarPicker_Tests-PureLayout */, + 561939E4515B71341136E16E /* Pods-TabBarPicker_Tests-TabBarPicker */, + C26F15991223F90FD04DB84A /* Pods-TabBarPicker_Tests-TabBarPicker-TabBarPicker */, + CF3DCEB04961FDED1CAC4B7D /* Pods-TabBarPicker_Tests-pop */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 3C6C6E272796555543FDDD24 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 352A750A926CD6A3FD798789 /* TabBarPicker.bundle in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 57DD5422982ACFD674C97697 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 901FC6E11A04D8CA4B1F8CE2 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + BC59ECA047DB5F78B01D591A /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + DFFD167800AA5C7FB04156CE /* TabBarPicker.bundle in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 224D255F6619A9EE8DCF1F89 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6F4F6E1692E952C3DF70CC77 /* FBSnapshotTestCase.m in Sources */, + DF4005BF055A0E8B8ED44A2E /* FBSnapshotTestCasePlatform.m in Sources */, + 5CBC2056C4A92853FB8D6FC1 /* FBSnapshotTestController.m in Sources */, + 6AF6567DABEF6C271FBB18EF /* Pods-TabBarPicker_Tests-FBSnapshotTestCase-dummy.m in Sources */, + 8F4C1C2AB5F72BD79C715288 /* SwiftSupport.swift in Sources */, + B4998C8B2DFBD10D384BEDAB /* UIImage+Compare.m in Sources */, + C3D2D049AB16D5AB12B9D2D4 /* UIImage+Diff.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7981162BCF60CBF79B62F96A /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8BE095C921BE6BA584278DF1 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 90800D06757C741CF1EA45A3 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 3B3B0386FC06E752FE9DAAC5 /* Pods-TabBarPicker_Tests-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + BB436824BBE685CB4A77D692 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 0AB2B13C89C0504EA2809C41 /* POPAnimatableProperty.mm in Sources */, + 63284F345CEB86A51188CD4C /* POPAnimation.mm in Sources */, + E1646D029B083ACD4AA09A1A /* POPAnimationEvent.mm in Sources */, + F2E41845989F5902E0EA80F2 /* POPAnimationExtras.mm in Sources */, + 056FF56B0E3FFCD1569FE5FA /* POPAnimationRuntime.mm in Sources */, + 9668EE579FCE6F10E8E7530B /* POPAnimationTracer.mm in Sources */, + CD7065E574AC2C89F9C3C91E /* POPAnimator.mm in Sources */, + A44C43086F269C7D7447CB70 /* POPBasicAnimation.mm in Sources */, + D713143B8698238B22FF78F8 /* POPCGUtils.mm in Sources */, + 324C7320C2ABF43BA6DEEFFE /* POPCustomAnimation.mm in Sources */, + E273ABADFA0DFA5557EDFE90 /* POPDecayAnimation.mm in Sources */, + 238EC5BEDA39C6E0C2C86E02 /* POPGeometry.mm in Sources */, + 6C1750B6604BA8C954F15225 /* POPLayerExtras.mm in Sources */, + DED28AA986D5385272CCB19A /* POPMath.mm in Sources */, + 3B3B3B4D7F1F2407A7BB8F06 /* POPPropertyAnimation.mm in Sources */, + 1B7951918B590B9BE7451E47 /* POPSpringAnimation.mm in Sources */, + B116AAD6A555AEA1B6301C0B /* POPVector.mm in Sources */, + 491B2C383677E49A8B176870 /* Pods-TabBarPicker_Tests-pop-dummy.m in Sources */, + 0E6AA18FEDB5F876D193D4A0 /* TransformationMatrix.cpp in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + BD5F548A0F7E932A81CF6FA0 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 85DEB4C5BC1A258172B2D9C9 /* Pods-TabBarPicker_Example-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + CCE054CBAA7C18EC4190E6A8 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + C24C05FE7938E208BC25AB47 /* Pods-TabBarPicker_Example-TabBarPicker-dummy.m in Sources */, + E03EE333F599DDEAC8D54CBA /* TabBarItem.m in Sources */, + 08E83A3AAFD5A55C25D691EB /* TabBarPicker.m in Sources */, + 87E34772E3D5DC2A38D13DCC /* TabBarSubItem.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + D3436181D8E54050939D3076 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 44933988DCE544FCDE73C91C /* Pods-TabBarPicker_Tests-TabBarPicker-dummy.m in Sources */, + 6C7EC292AC2406906C89C702 /* TabBarItem.m in Sources */, + 3E6ABA6E976EE9F358D84207 /* TabBarPicker.m in Sources */, + 09CF26836A1B5FFE7F41C3EB /* TabBarSubItem.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + E7F14378429DFFCE7EFFEC2A /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 00618A922B4BF903CD3FB0FB /* ALView+PureLayout.m in Sources */, + 100967E31D4539EDC982A5DB /* NSArray+PureLayout.m in Sources */, + 19E2E13BF272C622A6212CDF /* NSLayoutConstraint+PureLayout.m in Sources */, + 61852B1EC5A79D61D09833D8 /* Pods-TabBarPicker_Tests-PureLayout-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 2D1FCBF0F71D941BDE18AB4C /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "Pods-TabBarPicker_Tests-PureLayout"; + target = 3998475720C1C47684180202 /* Pods-TabBarPicker_Tests-PureLayout */; + targetProxy = 0EA9D3ECCF74DE7F75274BD5 /* PBXContainerItemProxy */; + }; + 3D385874E49584FB68248735 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "Pods-TabBarPicker_Tests-TabBarPicker-TabBarPicker"; + target = C26F15991223F90FD04DB84A /* Pods-TabBarPicker_Tests-TabBarPicker-TabBarPicker */; + targetProxy = 851C37FE16A19DB70AA57891 /* PBXContainerItemProxy */; + }; + 513C7CB9E2AD5FFFACAF085A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "Pods-TabBarPicker_Example-TabBarPicker-TabBarPicker"; + target = 8CA46A24F79F8A2591154DC8 /* Pods-TabBarPicker_Example-TabBarPicker-TabBarPicker */; + targetProxy = 1530225FC7A44B1ACA588ECC /* PBXContainerItemProxy */; + }; + 6681ABC2479B156BD4E4281B /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "Pods-TabBarPicker_Example-TabBarPicker"; + target = AE841CD8269D52D367EBAEBB /* Pods-TabBarPicker_Example-TabBarPicker */; + targetProxy = B025178FEAD646D2229BDD0B /* PBXContainerItemProxy */; + }; + 846F0B626200761F44F71507 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "Pods-TabBarPicker_Tests-TabBarPicker"; + target = 561939E4515B71341136E16E /* Pods-TabBarPicker_Tests-TabBarPicker */; + targetProxy = 6A2372653D3E44E2B0D68BC9 /* PBXContainerItemProxy */; + }; + C0DB0110D32ECDDB0A4AD0AB /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "Pods-TabBarPicker_Tests-pop"; + target = CF3DCEB04961FDED1CAC4B7D /* Pods-TabBarPicker_Tests-pop */; + targetProxy = F28FCFE320A7C1F1C2A78D0E /* PBXContainerItemProxy */; + }; + F9B7ECEE3092959AD130ECE4 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "Pods-TabBarPicker_Tests-FBSnapshotTestCase"; + target = 25EC7DE4FAEEEF84395686BD /* Pods-TabBarPicker_Tests-FBSnapshotTestCase */; + targetProxy = B244F2E681508765E9F87E57 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 005156B8A82199582027862A /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 0C7F9C9E234CA6AAF7F5EABE /* Pods-TabBarPicker_Example-TabBarPicker-Private.xcconfig */; + buildSettings = { + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Pods-TabBarPicker_Example"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + PRODUCT_NAME = TabBarPicker; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + WRAPPER_EXTENSION = bundle; + }; + name = Release; + }; + 0C282CF21104F91D2773C518 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = AD8368EA285B47BC5E4FC67A /* Pods-TabBarPicker_Tests-pop-Private.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_PREFIX_HEADER = "Target Support Files/Pods-TabBarPicker_Tests-pop/Pods-TabBarPicker_Tests-pop-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/Pods-TabBarPicker_Tests-pop/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 7.1; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MODULEMAP_FILE = "Target Support Files/Pods-TabBarPicker_Tests-pop/Pods-TabBarPicker_Tests-pop.modulemap"; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_NAME = pop; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 25A24F888CE568721C105B63 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = C6116B0D5A3B5F584BBC044D /* Pods-TabBarPicker_Tests.release.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + INFOPLIST_FILE = "Target Support Files/Pods-TabBarPicker_Tests/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 7.1; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MODULEMAP_FILE = "Target Support Files/Pods-TabBarPicker_Tests/Pods-TabBarPicker_Tests.modulemap"; + MTL_ENABLE_DEBUG_INFO = NO; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_NAME = Pods_TabBarPicker_Tests; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 315B18B284BC25DB07E3BE39 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E7E28C15EC58288F48C746F1 /* Pods-TabBarPicker_Tests-TabBarPicker-Private.xcconfig */; + buildSettings = { + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Pods-TabBarPicker_Tests"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + PRODUCT_NAME = TabBarPicker; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + WRAPPER_EXTENSION = bundle; + }; + name = Release; + }; + 33C4C2FD9FCF9F99133B3C8B /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 17F187FE6CA6214158010BBE /* Pods-TabBarPicker_Example.release.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + INFOPLIST_FILE = "Target Support Files/Pods-TabBarPicker_Example/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 7.1; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MODULEMAP_FILE = "Target Support Files/Pods-TabBarPicker_Example/Pods-TabBarPicker_Example.modulemap"; + MTL_ENABLE_DEBUG_INFO = NO; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_NAME = Pods_TabBarPicker_Example; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 4AA99F492820902385A5BAFE /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 7.1; + ONLY_ACTIVE_ARCH = YES; + STRIP_INSTALLED_PRODUCT = NO; + SYMROOT = "${SRCROOT}/../build"; + }; + name = Debug; + }; + 512355ABB693AF879D40B1C2 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 565784FDAE1E1414A1BB9D6A /* Pods-TabBarPicker_Tests-FBSnapshotTestCase-Private.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_PREFIX_HEADER = "Target Support Files/Pods-TabBarPicker_Tests-FBSnapshotTestCase/Pods-TabBarPicker_Tests-FBSnapshotTestCase-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/Pods-TabBarPicker_Tests-FBSnapshotTestCase/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 7.1; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MODULEMAP_FILE = "Target Support Files/Pods-TabBarPicker_Tests-FBSnapshotTestCase/Pods-TabBarPicker_Tests-FBSnapshotTestCase.modulemap"; + MTL_ENABLE_DEBUG_INFO = YES; + PRODUCT_NAME = FBSnapshotTestCase; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 60A0CFD22CC3D205395CB3C3 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = AD8368EA285B47BC5E4FC67A /* Pods-TabBarPicker_Tests-pop-Private.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_PREFIX_HEADER = "Target Support Files/Pods-TabBarPicker_Tests-pop/Pods-TabBarPicker_Tests-pop-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/Pods-TabBarPicker_Tests-pop/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 7.1; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MODULEMAP_FILE = "Target Support Files/Pods-TabBarPicker_Tests-pop/Pods-TabBarPicker_Tests-pop.modulemap"; + MTL_ENABLE_DEBUG_INFO = YES; + PRODUCT_NAME = pop; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 6AC7ADF82ECCFFB691F3B19B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = YES; + ENABLE_NS_ASSERTIONS = NO; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_PREPROCESSOR_DEFINITIONS = "RELEASE=1"; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 7.1; + STRIP_INSTALLED_PRODUCT = NO; + SYMROOT = "${SRCROOT}/../build"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 731DB4F93C95192D76867495 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E7E28C15EC58288F48C746F1 /* Pods-TabBarPicker_Tests-TabBarPicker-Private.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_PREFIX_HEADER = "Target Support Files/Pods-TabBarPicker_Tests-TabBarPicker/Pods-TabBarPicker_Tests-TabBarPicker-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/Pods-TabBarPicker_Tests-TabBarPicker/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 7.1; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MODULEMAP_FILE = "Target Support Files/Pods-TabBarPicker_Tests-TabBarPicker/Pods-TabBarPicker_Tests-TabBarPicker.modulemap"; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_NAME = TabBarPicker; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 80F390BA061CDA09CD783EF7 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9ACD1B64DC358C440E53AF49 /* Pods-TabBarPicker_Tests-PureLayout-Private.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_PREFIX_HEADER = "Target Support Files/Pods-TabBarPicker_Tests-PureLayout/Pods-TabBarPicker_Tests-PureLayout-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/Pods-TabBarPicker_Tests-PureLayout/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 7.1; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MODULEMAP_FILE = "Target Support Files/Pods-TabBarPicker_Tests-PureLayout/Pods-TabBarPicker_Tests-PureLayout.modulemap"; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_NAME = PureLayout; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 844B647CF6FEB1A53FB552BC /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 565784FDAE1E1414A1BB9D6A /* Pods-TabBarPicker_Tests-FBSnapshotTestCase-Private.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_PREFIX_HEADER = "Target Support Files/Pods-TabBarPicker_Tests-FBSnapshotTestCase/Pods-TabBarPicker_Tests-FBSnapshotTestCase-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/Pods-TabBarPicker_Tests-FBSnapshotTestCase/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 7.1; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MODULEMAP_FILE = "Target Support Files/Pods-TabBarPicker_Tests-FBSnapshotTestCase/Pods-TabBarPicker_Tests-FBSnapshotTestCase.modulemap"; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_NAME = FBSnapshotTestCase; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 981C452610C3F8FCB9714754 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9ACD1B64DC358C440E53AF49 /* Pods-TabBarPicker_Tests-PureLayout-Private.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_PREFIX_HEADER = "Target Support Files/Pods-TabBarPicker_Tests-PureLayout/Pods-TabBarPicker_Tests-PureLayout-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/Pods-TabBarPicker_Tests-PureLayout/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 7.1; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MODULEMAP_FILE = "Target Support Files/Pods-TabBarPicker_Tests-PureLayout/Pods-TabBarPicker_Tests-PureLayout.modulemap"; + MTL_ENABLE_DEBUG_INFO = YES; + PRODUCT_NAME = PureLayout; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + A25A86707D96F1CFBE733378 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 0C7F9C9E234CA6AAF7F5EABE /* Pods-TabBarPicker_Example-TabBarPicker-Private.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_PREFIX_HEADER = "Target Support Files/Pods-TabBarPicker_Example-TabBarPicker/Pods-TabBarPicker_Example-TabBarPicker-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/Pods-TabBarPicker_Example-TabBarPicker/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 7.1; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MODULEMAP_FILE = "Target Support Files/Pods-TabBarPicker_Example-TabBarPicker/Pods-TabBarPicker_Example-TabBarPicker.modulemap"; + MTL_ENABLE_DEBUG_INFO = YES; + PRODUCT_NAME = TabBarPicker; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + AEEA9C97B37DD3AEFA968A82 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 2097A7EF439D99B2BE1C3D1C /* Pods-TabBarPicker_Tests.debug.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + INFOPLIST_FILE = "Target Support Files/Pods-TabBarPicker_Tests/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 7.1; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MODULEMAP_FILE = "Target Support Files/Pods-TabBarPicker_Tests/Pods-TabBarPicker_Tests.modulemap"; + MTL_ENABLE_DEBUG_INFO = YES; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_NAME = Pods_TabBarPicker_Tests; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + C33C4F014501BCF839F614D1 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 0C7F9C9E234CA6AAF7F5EABE /* Pods-TabBarPicker_Example-TabBarPicker-Private.xcconfig */; + buildSettings = { + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Pods-TabBarPicker_Example"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + PRODUCT_NAME = TabBarPicker; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + WRAPPER_EXTENSION = bundle; + }; + name = Debug; + }; + DA3523B2598EACCCE9CB261B /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E7E28C15EC58288F48C746F1 /* Pods-TabBarPicker_Tests-TabBarPicker-Private.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_PREFIX_HEADER = "Target Support Files/Pods-TabBarPicker_Tests-TabBarPicker/Pods-TabBarPicker_Tests-TabBarPicker-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/Pods-TabBarPicker_Tests-TabBarPicker/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 7.1; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MODULEMAP_FILE = "Target Support Files/Pods-TabBarPicker_Tests-TabBarPicker/Pods-TabBarPicker_Tests-TabBarPicker.modulemap"; + MTL_ENABLE_DEBUG_INFO = YES; + PRODUCT_NAME = TabBarPicker; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + DF8E85A9C5DC81D0532229BE /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 3608461BC17424EEE0E93928 /* Pods-TabBarPicker_Example.debug.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + INFOPLIST_FILE = "Target Support Files/Pods-TabBarPicker_Example/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 7.1; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MODULEMAP_FILE = "Target Support Files/Pods-TabBarPicker_Example/Pods-TabBarPicker_Example.modulemap"; + MTL_ENABLE_DEBUG_INFO = YES; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_NAME = Pods_TabBarPicker_Example; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + E26F32E7B66DC04E036412B6 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 0C7F9C9E234CA6AAF7F5EABE /* Pods-TabBarPicker_Example-TabBarPicker-Private.xcconfig */; + buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_PREFIX_HEADER = "Target Support Files/Pods-TabBarPicker_Example-TabBarPicker/Pods-TabBarPicker_Example-TabBarPicker-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/Pods-TabBarPicker_Example-TabBarPicker/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 7.1; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MODULEMAP_FILE = "Target Support Files/Pods-TabBarPicker_Example-TabBarPicker/Pods-TabBarPicker_Example-TabBarPicker.modulemap"; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_NAME = TabBarPicker; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + F4762A1FD393DCDA04C9585C /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E7E28C15EC58288F48C746F1 /* Pods-TabBarPicker_Tests-TabBarPicker-Private.xcconfig */; + buildSettings = { + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Pods-TabBarPicker_Tests"; + ENABLE_STRICT_OBJC_MSGSEND = YES; + PRODUCT_NAME = TabBarPicker; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + WRAPPER_EXTENSION = bundle; + }; + name = Debug; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1249393950AA2AFADACAB1CB /* Build configuration list for PBXNativeTarget "Pods-TabBarPicker_Tests-TabBarPicker" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DA3523B2598EACCCE9CB261B /* Debug */, + 731DB4F93C95192D76867495 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 27426159E1BA8D677C1F5403 /* Build configuration list for PBXNativeTarget "Pods-TabBarPicker_Tests-TabBarPicker-TabBarPicker" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F4762A1FD393DCDA04C9585C /* Debug */, + 315B18B284BC25DB07E3BE39 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 47ACCA4578EB0CE15C6A5317 /* Build configuration list for PBXNativeTarget "Pods-TabBarPicker_Example-TabBarPicker-TabBarPicker" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C33C4F014501BCF839F614D1 /* Debug */, + 005156B8A82199582027862A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 67F910D5E6FB101761D3287A /* Build configuration list for PBXNativeTarget "Pods-TabBarPicker_Tests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + AEEA9C97B37DD3AEFA968A82 /* Debug */, + 25A24F888CE568721C105B63 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 8CE83C4A2D070D01A02146BC /* Build configuration list for PBXNativeTarget "Pods-TabBarPicker_Example" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DF8E85A9C5DC81D0532229BE /* Debug */, + 33C4C2FD9FCF9F99133B3C8B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 9AE8E44F818B51C74314F350 /* Build configuration list for PBXNativeTarget "Pods-TabBarPicker_Tests-FBSnapshotTestCase" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 512355ABB693AF879D40B1C2 /* Debug */, + 844B647CF6FEB1A53FB552BC /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + A9984B49EB9549F746394505 /* Build configuration list for PBXProject "Pods" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4AA99F492820902385A5BAFE /* Debug */, + 6AC7ADF82ECCFFB691F3B19B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + ADA31270D06F7C2E2E1867DA /* Build configuration list for PBXNativeTarget "Pods-TabBarPicker_Example-TabBarPicker" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + A25A86707D96F1CFBE733378 /* Debug */, + E26F32E7B66DC04E036412B6 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E2A01AEE9484A7CAC7FAF8E1 /* Build configuration list for PBXNativeTarget "Pods-TabBarPicker_Tests-PureLayout" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 981C452610C3F8FCB9714754 /* Debug */, + 80F390BA061CDA09CD783EF7 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E923A51F7294D674E9BAB4F1 /* Build configuration list for PBXNativeTarget "Pods-TabBarPicker_Tests-pop" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 60A0CFD22CC3D205395CB3C3 /* Debug */, + 0C282CF21104F91D2773C518 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = D9442BE4A2137345B01F164F /* Project object */; +} diff --git a/Example/Pods/Pods.xcodeproj/xcshareddata/xcschemes/Pods-TabBarPicker_Example-TabBarPicker-TabBarPicker.xcscheme b/Example/Pods/Pods.xcodeproj/xcshareddata/xcschemes/Pods-TabBarPicker_Example-TabBarPicker-TabBarPicker.xcscheme new file mode 100644 index 0000000..b981551 --- /dev/null +++ b/Example/Pods/Pods.xcodeproj/xcshareddata/xcschemes/Pods-TabBarPicker_Example-TabBarPicker-TabBarPicker.xcscheme @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Example/Pods/Pods.xcodeproj/xcshareddata/xcschemes/Pods-TabBarPicker_Example-TabBarPicker.xcscheme b/Example/Pods/Pods.xcodeproj/xcshareddata/xcschemes/Pods-TabBarPicker_Example-TabBarPicker.xcscheme new file mode 100644 index 0000000..e4eeade --- /dev/null +++ b/Example/Pods/Pods.xcodeproj/xcshareddata/xcschemes/Pods-TabBarPicker_Example-TabBarPicker.xcscheme @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Example/Pods/Pods.xcodeproj/xcshareddata/xcschemes/Pods-TabBarPicker_Tests-TabBarPicker-TabBarPicker.xcscheme b/Example/Pods/Pods.xcodeproj/xcshareddata/xcschemes/Pods-TabBarPicker_Tests-TabBarPicker-TabBarPicker.xcscheme new file mode 100644 index 0000000..bd0383f --- /dev/null +++ b/Example/Pods/Pods.xcodeproj/xcshareddata/xcschemes/Pods-TabBarPicker_Tests-TabBarPicker-TabBarPicker.xcscheme @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Example/Pods/Pods.xcodeproj/xcshareddata/xcschemes/Pods-TabBarPicker_Tests-TabBarPicker.xcscheme b/Example/Pods/Pods.xcodeproj/xcshareddata/xcschemes/Pods-TabBarPicker_Tests-TabBarPicker.xcscheme new file mode 100644 index 0000000..2a88c2a --- /dev/null +++ b/Example/Pods/Pods.xcodeproj/xcshareddata/xcschemes/Pods-TabBarPicker_Tests-TabBarPicker.xcscheme @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Example/Pods/PureLayout/LICENSE b/Example/Pods/PureLayout/LICENSE new file mode 100755 index 0000000..5396bc0 --- /dev/null +++ b/Example/Pods/PureLayout/LICENSE @@ -0,0 +1,9 @@ +This code is distributed under the terms and conditions of the MIT license. + +Copyright (c) 2014-2015 Tyler Fox + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/Example/Pods/PureLayout/PureLayout/PureLayout/ALView+PureLayout.h b/Example/Pods/PureLayout/PureLayout/PureLayout/ALView+PureLayout.h new file mode 100755 index 0000000..ae74922 --- /dev/null +++ b/Example/Pods/PureLayout/PureLayout/PureLayout/ALView+PureLayout.h @@ -0,0 +1,253 @@ +// +// ALView+PureLayout.h +// v2.0.5 +// https://github.com/smileyborg/PureLayout +// +// Copyright (c) 2012 Richard Turton +// Copyright (c) 2013-2015 Tyler Fox +// +// This code is distributed under the terms and conditions of the MIT license. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +#import "PureLayoutDefines.h" + + +#pragma mark - ALView+PureLayout + +/** + A category on UIView/NSView that provides a simple yet powerful interface for creating Auto Layout constraints. + */ +@interface ALView (PureLayout) + + +#pragma mark Factory & Initializer Methods + +/** Creates and returns a new view that does not convert the autoresizing mask into constraints. */ ++ (instancetype)newAutoLayoutView; + +/** Initializes and returns a new view that does not convert the autoresizing mask into constraints. */ +- (instancetype)initForAutoLayout; + + +#pragma mark Create Constraints Without Installing + +/** Prevents constraints created in the given constraints block from being automatically installed (activated). + The constraints created from calls to the PureLayout API in the block are returned in a single array. */ ++ (NSArray *)autoCreateConstraintsWithoutInstalling:(ALConstraintsBlock)block; + + +#pragma mark Set Priority For Constraints + +/** Sets the constraint priority to the given value for all constraints created using the PureLayout API within the given constraints block. + NOTE: This method will have no effect (and will NOT set the priority) on constraints created or added without using the PureLayout API! */ ++ (void)autoSetPriority:(ALLayoutPriority)priority forConstraints:(ALConstraintsBlock)block; + + +#pragma mark Set Identifier For Constraints + +#if __PureLayout_MinBaseSDK_iOS_8_0 + +/** Sets the identifier for all constraints created using the PureLayout API within the given constraints block. + NOTE: This method will have no effect (and will NOT set the identifier) on constraints created or added without using the PureLayout API! */ ++ (void)autoSetIdentifier:(NSString *)identifier forConstraints:(ALConstraintsBlock)block; + +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 */ + + +#pragma mark Center & Align in Superview + +/** Centers the view in its superview. */ +- (NSArray *)autoCenterInSuperview; + +/** Aligns the view to the same axis of its superview. */ +- (NSLayoutConstraint *)autoAlignAxisToSuperviewAxis:(ALAxis)axis; + +#if __PureLayout_MinBaseSDK_iOS_8_0 + +/** Centers the view in its superview's margins. Available in iOS 8.0 and later. */ +- (NSArray *)autoCenterInSuperviewMargins; + +/** Aligns the view to the corresponding margin axis of its superview. Available in iOS 8.0 and later. */ +- (NSLayoutConstraint *)autoAlignAxisToSuperviewMarginAxis:(ALAxis)axis; + +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 */ + + +#pragma mark Pin Edges to Superview + +/** Pins the given edge of the view to the same edge of its superview. */ +- (NSLayoutConstraint *)autoPinEdgeToSuperviewEdge:(ALEdge)edge; + +/** Pins the given edge of the view to the same edge of its superview with an inset. */ +- (NSLayoutConstraint *)autoPinEdgeToSuperviewEdge:(ALEdge)edge withInset:(CGFloat)inset; + +/** Pins the given edge of the view to the same edge of its superview with an inset as a maximum or minimum. */ +- (NSLayoutConstraint *)autoPinEdgeToSuperviewEdge:(ALEdge)edge withInset:(CGFloat)inset relation:(NSLayoutRelation)relation; + +/** Pins the edges of the view to the edges of its superview with the given edge insets. */ +- (NSArray *)autoPinEdgesToSuperviewEdgesWithInsets:(ALEdgeInsets)insets; + +/** Pins 3 of the 4 edges of the view to the edges of its superview with the given edge insets, excluding one edge. */ +- (NSArray *)autoPinEdgesToSuperviewEdgesWithInsets:(ALEdgeInsets)insets excludingEdge:(ALEdge)edge; + +#if __PureLayout_MinBaseSDK_iOS_8_0 + +/** Pins the given edge of the view to the corresponding margin of its superview. Available in iOS 8.0 and later. */ +- (NSLayoutConstraint *)autoPinEdgeToSuperviewMargin:(ALEdge)edge; + +/** Pins the given edge of the view to the corresponding margin of its superview as a maximum or minimum. Available in iOS 8.0 and later. */ +- (NSLayoutConstraint *)autoPinEdgeToSuperviewMargin:(ALEdge)edge relation:(NSLayoutRelation)relation; + +/** Pins the edges of the view to the margins of its superview. Available in iOS 8.0 and later. */ +- (NSArray *)autoPinEdgesToSuperviewMargins; + +/** Pins 3 of the 4 edges of the view to the margins of its superview excluding one edge. Available in iOS 8.0 and later. */ +- (NSArray *)autoPinEdgesToSuperviewMarginsExcludingEdge:(ALEdge)edge; + +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 */ + + +#pragma mark Pin Edges + +/** Pins an edge of the view to a given edge of another view. */ +- (NSLayoutConstraint *)autoPinEdge:(ALEdge)edge toEdge:(ALEdge)toEdge ofView:(ALView *)otherView; + +/** Pins an edge of the view to a given edge of another view with an offset. */ +- (NSLayoutConstraint *)autoPinEdge:(ALEdge)edge toEdge:(ALEdge)toEdge ofView:(ALView *)otherView withOffset:(CGFloat)offset; + +/** Pins an edge of the view to a given edge of another view with an offset as a maximum or minimum. */ +- (NSLayoutConstraint *)autoPinEdge:(ALEdge)edge toEdge:(ALEdge)toEdge ofView:(ALView *)otherView withOffset:(CGFloat)offset relation:(NSLayoutRelation)relation; + + +#pragma mark Align Axes + +/** Aligns an axis of the view to the same axis of another view. */ +- (NSLayoutConstraint *)autoAlignAxis:(ALAxis)axis toSameAxisOfView:(ALView *)otherView; + +/** Aligns an axis of the view to the same axis of another view with an offset. */ +- (NSLayoutConstraint *)autoAlignAxis:(ALAxis)axis toSameAxisOfView:(ALView *)otherView withOffset:(CGFloat)offset; + + +#pragma mark Match Dimensions + +/** Matches a dimension of the view to a given dimension of another view. */ +- (NSLayoutConstraint *)autoMatchDimension:(ALDimension)dimension toDimension:(ALDimension)toDimension ofView:(ALView *)otherView; + +/** Matches a dimension of the view to a given dimension of another view with an offset. */ +- (NSLayoutConstraint *)autoMatchDimension:(ALDimension)dimension toDimension:(ALDimension)toDimension ofView:(ALView *)otherView withOffset:(CGFloat)offset; + +/** Matches a dimension of the view to a given dimension of another view with an offset as a maximum or minimum. */ +- (NSLayoutConstraint *)autoMatchDimension:(ALDimension)dimension toDimension:(ALDimension)toDimension ofView:(ALView *)otherView withOffset:(CGFloat)offset relation:(NSLayoutRelation)relation; + +/** Matches a dimension of the view to a multiple of a given dimension of another view. */ +- (NSLayoutConstraint *)autoMatchDimension:(ALDimension)dimension toDimension:(ALDimension)toDimension ofView:(ALView *)otherView withMultiplier:(CGFloat)multiplier; + +/** Matches a dimension of the view to a multiple of a given dimension of another view as a maximum or minimum. */ +- (NSLayoutConstraint *)autoMatchDimension:(ALDimension)dimension toDimension:(ALDimension)toDimension ofView:(ALView *)otherView withMultiplier:(CGFloat)multiplier relation:(NSLayoutRelation)relation; + + +#pragma mark Set Dimensions + +/** Sets the view to a specific size. */ +- (NSArray *)autoSetDimensionsToSize:(CGSize)size; + +/** Sets the given dimension of the view to a specific size. */ +- (NSLayoutConstraint *)autoSetDimension:(ALDimension)dimension toSize:(CGFloat)size; + +/** Sets the given dimension of the view to a specific size as a maximum or minimum. */ +- (NSLayoutConstraint *)autoSetDimension:(ALDimension)dimension toSize:(CGFloat)size relation:(NSLayoutRelation)relation; + + +#pragma mark Set Content Compression Resistance & Hugging + +/** Sets the priority of content compression resistance for an axis. + NOTE: This method must be called from within the block passed into the method +[UIView autoSetPriority:forConstraints:] */ +- (void)autoSetContentCompressionResistancePriorityForAxis:(ALAxis)axis; + +/** Sets the priority of content hugging for an axis. + NOTE: This method must be called from within the block passed into the method +[UIView autoSetPriority:forConstraints:] */ +- (void)autoSetContentHuggingPriorityForAxis:(ALAxis)axis; + + +#pragma mark Constrain Any Attributes + +/** Constrains an attribute of the view to a given attribute of another view. */ +- (NSLayoutConstraint *)autoConstrainAttribute:(ALAttribute)attribute toAttribute:(ALAttribute)toAttribute ofView:(ALView *)otherView; + +/** Constrains an attribute of the view to a given attribute of another view with an offset. */ +- (NSLayoutConstraint *)autoConstrainAttribute:(ALAttribute)attribute toAttribute:(ALAttribute)toAttribute ofView:(ALView *)otherView withOffset:(CGFloat)offset; + +/** Constrains an attribute of the view to a given attribute of another view with an offset as a maximum or minimum. */ +- (NSLayoutConstraint *)autoConstrainAttribute:(ALAttribute)attribute toAttribute:(ALAttribute)toAttribute ofView:(ALView *)otherView withOffset:(CGFloat)offset relation:(NSLayoutRelation)relation; + +/** Constrains an attribute of the view to a given attribute of another view with a multiplier. */ +- (NSLayoutConstraint *)autoConstrainAttribute:(ALAttribute)attribute toAttribute:(ALAttribute)toAttribute ofView:(ALView *)otherView withMultiplier:(CGFloat)multiplier; + +/** Constrains an attribute of the view to a given attribute of another view with a multiplier as a maximum or minimum. */ +- (NSLayoutConstraint *)autoConstrainAttribute:(ALAttribute)attribute toAttribute:(ALAttribute)toAttribute ofView:(ALView *)otherView withMultiplier:(CGFloat)multiplier relation:(NSLayoutRelation)relation; + + +#pragma mark Pin to Layout Guides (iOS only) + +#if TARGET_OS_IPHONE + +/** Pins the top edge of the view to the top layout guide of the given view controller with an inset. Available on iOS only. */ +- (NSLayoutConstraint *)autoPinToTopLayoutGuideOfViewController:(UIViewController *)viewController withInset:(CGFloat)inset; + +/** Pins the top edge of the view to the top layout guide of the given view controller with an inset as a maximum or minimum. Available on iOS only. */ +- (NSLayoutConstraint *)autoPinToTopLayoutGuideOfViewController:(UIViewController *)viewController withInset:(CGFloat)inset relation:(NSLayoutRelation)relation; + +/** Pins the bottom edge of the view to the bottom layout guide of the given view controller with an inset. Available on iOS only. */ +- (NSLayoutConstraint *)autoPinToBottomLayoutGuideOfViewController:(UIViewController *)viewController withInset:(CGFloat)inset; + +/** Pins the bottom edge of the view to the bottom layout guide of the given view controller with an inset as a maximum or minimum. Available on iOS only. */ +- (NSLayoutConstraint *)autoPinToBottomLayoutGuideOfViewController:(UIViewController *)viewController withInset:(CGFloat)inset relation:(NSLayoutRelation)relation; + +#endif /* TARGET_OS_IPHONE */ + + +#pragma mark Deprecated Methods + +/** DEPRECATED as of PureLayout v2.0.0. Retain a reference to and remove specific constraints instead, or recreate the view(s) entirely to remove all constraints. + Removes all explicit constraints that affect the view. + WARNING: Apple's constraint solver is not optimized for large-scale constraint removal; you may encounter major performance issues after using this method. + NOTE: This method preserves implicit constraints, such as intrinsic content size constraints, which you usually do not want to remove. */ +- (void)autoRemoveConstraintsAffectingView __attribute__((deprecated)); + +/** DEPRECATED as of PureLayout v2.0.0. Retain a reference to and remove specific constraints instead, or recreate the view(s) entirely to remove all constraints. + Removes all constraints that affect the view, optionally including implicit constraints. + WARNING: Apple's constraint solver is not optimized for large-scale constraint removal; you may encounter major performance issues after using this method. + NOTE: Implicit constraints are auto-generated lower priority constraints, and you usually do not want to remove these. */ +- (void)autoRemoveConstraintsAffectingViewIncludingImplicitConstraints:(BOOL)shouldRemoveImplicitConstraints __attribute__((deprecated)); + +/** DEPRECATED as of PureLayout v2.0.0. Retain a reference to and remove specific constraints instead, or recreate the view(s) entirely to remove all constraints. + Recursively removes all explicit constraints that affect the view and its subviews. + WARNING: Apple's constraint solver is not optimized for large-scale constraint removal; you may encounter major performance issues after using this method. + NOTE: This method preserves implicit constraints, such as intrinsic content size constraints, which you usually do not want to remove. */ +- (void)autoRemoveConstraintsAffectingViewAndSubviews __attribute__((deprecated)); + +/** DEPRECATED as of PureLayout v2.0.0. Retain a reference to and remove specific constraints instead, or recreate the view(s) entirely to remove all constraints. + Recursively removes all constraints from the view and its subviews, optionally including implicit constraints. + WARNING: Apple's constraint solver is not optimized for large-scale constraint removal; you may encounter major performance issues after using this method. + NOTE: Implicit constraints are auto-generated lower priority constraints, and you usually do not want to remove these. */ +- (void)autoRemoveConstraintsAffectingViewAndSubviewsIncludingImplicitConstraints:(BOOL)shouldRemoveImplicitConstraints __attribute__((deprecated)); + +@end diff --git a/Example/Pods/PureLayout/PureLayout/PureLayout/ALView+PureLayout.m b/Example/Pods/PureLayout/PureLayout/PureLayout/ALView+PureLayout.m new file mode 100755 index 0000000..81817ca --- /dev/null +++ b/Example/Pods/PureLayout/PureLayout/PureLayout/ALView+PureLayout.m @@ -0,0 +1,1102 @@ +// +// ALView+PureLayout.m +// v2.0.5 +// https://github.com/smileyborg/PureLayout +// +// Copyright (c) 2012 Richard Turton +// Copyright (c) 2013-2015 Tyler Fox +// +// This code is distributed under the terms and conditions of the MIT license. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +#import "ALView+PureLayout.h" +#import "NSLayoutConstraint+PureLayout.h" +#import "NSArray+PureLayout.h" +#import "PureLayout+Internal.h" + + +#pragma mark - ALView+PureLayout + +@implementation ALView (PureLayout) + + +#pragma mark Factory & Initializer Methods + +/** + Creates and returns a new view that does not convert the autoresizing mask into constraints. + */ ++ (instancetype)newAutoLayoutView +{ + ALView *view = [self new]; + view.translatesAutoresizingMaskIntoConstraints = NO; + return view; +} + +/** + Initializes and returns a new view that does not convert the autoresizing mask into constraints. + */ +- (instancetype)initForAutoLayout +{ + self = [self init]; + if (self) { + self.translatesAutoresizingMaskIntoConstraints = NO; + } + return self; +} + + +#pragma mark Create Constraints Without Installing + +/** + A global variable that stores a stack of arrays of constraints created without being immediately installed. + When executing a constraints block passed into the +[autoCreateConstraintsWithoutInstalling:] method, a new + mutable array is pushed onto this stack, and all constraints created with PureLayout in the block are added + to this array. When the block finishes executing, the array is popped off this stack. Automatic constraint + installation is prevented if this stack contains at least 1 array. + + NOTE: Access to this variable is not synchronized (and should only be done on the main thread). + */ +static NSMutableArray *_al_arraysOfCreatedConstraints = nil; + +/** + Accessor for the global state that stores arrays of constraints created without being installed. + */ ++ (NSMutableArray *)al_arraysOfCreatedConstraints +{ + if (!_al_arraysOfCreatedConstraints) { + _al_arraysOfCreatedConstraints = [NSMutableArray new]; + } + return _al_arraysOfCreatedConstraints; +} + +/** + Accessor for the current mutable array of constraints created without being immediately installed. + */ ++ (NSMutableArray *)al_currentArrayOfCreatedConstraints +{ + return [[self al_arraysOfCreatedConstraints] lastObject]; +} + +/** + Accessor for the global state that determines whether automatic constraint installation should be prevented. + */ ++ (BOOL)al_preventAutomaticConstraintInstallation +{ + return [[self al_arraysOfCreatedConstraints] count] > 0; +} + +/** + Prevents constraints created in the given constraints block from being automatically installed (activated). + The constraints created from calls to the PureLayout API in the block are returned in a single array. + + @param block A block of method calls to the PureLayout API that create constraints. + @return An array of the constraints that were created from calls to the PureLayout API inside the block. + */ ++ (NSArray *)autoCreateConstraintsWithoutInstalling:(ALConstraintsBlock)block +{ + NSAssert(block, @"The constraints block cannot be nil."); + NSArray *createdConstraints = nil; + if (block) { + [[self al_arraysOfCreatedConstraints] addObject:[NSMutableArray new]]; + block(); + createdConstraints = [self al_currentArrayOfCreatedConstraints]; + [[self al_arraysOfCreatedConstraints] removeLastObject]; + } + return createdConstraints; +} + + +#pragma mark Set Priority For Constraints + +/** + A global variable that stores a stack of layout priorities to set on constraints. + When executing a constraints block passed into the +[autoSetPriority:forConstraints:] method, the priority for + that call is pushed onto this stack, and when the block finishes executing, that priority is popped off this + stack. If this stack contains at least 1 priority, the priority at the top of the stack will be set for all + constraints created by this library (even if automatic constraint installation is being prevented). + NOTE: Access to this variable is not synchronized (and should only be done on the main thread). + */ +static NSMutableArray *_al_globalConstraintPriorities = nil; + +/** + Accessor for the global stack of layout priorities. + */ ++ (NSMutableArray *)al_globalConstraintPriorities +{ + if (!_al_globalConstraintPriorities) { + _al_globalConstraintPriorities = [NSMutableArray new]; + } + return _al_globalConstraintPriorities; +} + +/** + Returns the current layout priority to use for constraints. + When executing a constraints block passed into +[autoSetPriority:forConstraints:], this will return + the priority for the current block. Otherwise, the default Required priority is returned. + */ ++ (ALLayoutPriority)al_currentGlobalConstraintPriority +{ + NSMutableArray *globalConstraintPriorities = [self al_globalConstraintPriorities]; + if ([globalConstraintPriorities count] == 0) { + return ALLayoutPriorityRequired; + } + return [[globalConstraintPriorities lastObject] floatValue]; +} + +/** + Accessor for the global state that determines if we're currently in the scope of a priority constraints block. + */ ++ (BOOL)al_isExecutingPriorityConstraintsBlock +{ + return [[self al_globalConstraintPriorities] count] > 0; +} + +/** + Sets the constraint priority to the given value for all constraints created using the PureLayout + API within the given constraints block. + + NOTE: This method will have no effect (and will NOT set the priority) on constraints created or added + without using the PureLayout API! + + @param priority The layout priority to be set on all constraints created in the constraints block. + @param block A block of method calls to the PureLayout API that create and install constraints. + */ ++ (void)autoSetPriority:(ALLayoutPriority)priority forConstraints:(ALConstraintsBlock)block +{ + NSAssert(block, @"The constraints block cannot be nil."); + if (block) { + [[self al_globalConstraintPriorities] addObject:@(priority)]; + block(); + [[self al_globalConstraintPriorities] removeLastObject]; + } +} + + +#pragma mark Set Identifier For Constraints + +#if __PureLayout_MinBaseSDK_iOS_8_0 + +/** + A global variable that stores a stack of identifier strings to set on constraints. + When executing a constraints block passed into the +[autoSetIdentifier:forConstraints:] method, the identifier for + that call is pushed onto this stack, and when the block finishes executing, that identifier is popped off this + stack. If this stack contains at least 1 identifier, the identifier at the top of the stack will be set for all + constraints created by this library (even if automatic constraint installation is being prevented). + NOTE: Access to this variable is not synchronized (and should only be done on the main thread). + */ +static NSMutableArray *_al_globalConstraintIdentifiers = nil; + +/** + Accessor for the global state of constraint identifiers. + */ ++ (NSMutableArray *)al_globalConstraintIdentifiers +{ + if (!_al_globalConstraintIdentifiers) { + _al_globalConstraintIdentifiers = [NSMutableArray new]; + } + return _al_globalConstraintIdentifiers; +} + +/** + Returns the current identifier string to use for constraints. + When executing a constraints block passed into +[autoSetIdentifier:forConstraints:], this will return + the identifier for the current block. Otherwise, nil is returned. + */ ++ (NSString *)al_currentGlobalConstraintIdentifier +{ + NSMutableArray *globalConstraintIdentifiers = [self al_globalConstraintIdentifiers]; + if ([globalConstraintIdentifiers count] == 0) { + return nil; + } + return [globalConstraintIdentifiers lastObject]; +} + +/** + Sets the identifier for all constraints created using the PureLayout API within the given constraints block. + + NOTE: This method will have no effect (and will NOT set the identifier) on constraints created or added + without using the PureLayout API! + + @param identifier A string used to identify all constraints created in the constraints block. + @param block A block of method calls to the PureLayout API that create and install constraints. + */ ++ (void)autoSetIdentifier:(NSString *)identifier forConstraints:(ALConstraintsBlock)block +{ + NSAssert(block, @"The constraints block cannot be nil."); + NSAssert(identifier, @"The identifier string cannot be nil."); + if (block) { + if (identifier) { + [[self al_globalConstraintIdentifiers] addObject:identifier]; + } + block(); + if (identifier) { + [[self al_globalConstraintIdentifiers] removeLastObject]; + } + } +} + +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 */ + + +#pragma mark Center in Superview + +/** + Centers the view in its superview. + + @return An array of constraints added. + */ +- (NSArray *)autoCenterInSuperview +{ + NSMutableArray *constraints = [NSMutableArray new]; + [constraints addObject:[self autoAlignAxisToSuperviewAxis:ALAxisHorizontal]]; + [constraints addObject:[self autoAlignAxisToSuperviewAxis:ALAxisVertical]]; + return constraints; +} + +/** + Aligns the view to the same axis of its superview. + + @param axis The axis of this view and of its superview to align. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoAlignAxisToSuperviewAxis:(ALAxis)axis +{ + self.translatesAutoresizingMaskIntoConstraints = NO; + ALView *superview = self.superview; + NSAssert(superview, @"View's superview must not be nil.\nView: %@", self); + return [self autoConstrainAttribute:(ALAttribute)axis toAttribute:(ALAttribute)axis ofView:superview]; +} + +#if __PureLayout_MinBaseSDK_iOS_8_0 + +/** + Centers the view in its superview, taking into account the layout margins of both the view and its superview. + + @return An array of constraints added. + */ +- (NSArray *)autoCenterInSuperviewMargins +{ + NSMutableArray *constraints = [NSMutableArray new]; + [constraints addObject:[self autoAlignAxisToSuperviewMarginAxis:ALAxisHorizontal]]; + [constraints addObject:[self autoAlignAxisToSuperviewMarginAxis:ALAxisVertical]]; + return constraints; +} + +/** + Aligns the view to the corresponding margin axis of its superview. + + @param axis The axis of this view to align to the corresponding margin axis of its superview. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoAlignAxisToSuperviewMarginAxis:(ALAxis)axis +{ + self.translatesAutoresizingMaskIntoConstraints = NO; + ALView *superview = self.superview; + NSAssert(superview, @"View's superview must not be nil.\nView: %@", self); + ALMarginAxis marginAxis = [NSLayoutConstraint al_marginAxisForAxis:axis]; + return [self autoConstrainAttribute:(ALAttribute)axis toAttribute:(ALAttribute)marginAxis ofView:superview]; +} + +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 */ + + +#pragma mark Pin Edges to Superview + +/** + Pins the given edge of the view to the same edge of its superview. + + @param edge The edge of this view and its superview to pin. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoPinEdgeToSuperviewEdge:(ALEdge)edge +{ + return [self autoPinEdgeToSuperviewEdge:edge withInset:0.0]; +} + +/** + Pins the given edge of the view to the same edge of its superview with an inset. + + @param edge The edge of this view and its superview to pin. + @param inset The amount to inset this view's edge from the superview's edge. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoPinEdgeToSuperviewEdge:(ALEdge)edge withInset:(CGFloat)inset +{ + return [self autoPinEdgeToSuperviewEdge:edge withInset:inset relation:NSLayoutRelationEqual]; +} + +/** + Pins the given edge of the view to the same edge of its superview with an inset as a maximum or minimum. + + @param edge The edge of this view and its superview to pin. + @param inset The amount to inset this view's edge from the superview's edge. + @param relation Whether the inset should be at least, at most, or exactly equal to the given value. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoPinEdgeToSuperviewEdge:(ALEdge)edge withInset:(CGFloat)inset relation:(NSLayoutRelation)relation +{ + self.translatesAutoresizingMaskIntoConstraints = NO; + ALView *superview = self.superview; + NSAssert(superview, @"View's superview must not be nil.\nView: %@", self); + if (edge == ALEdgeBottom || edge == ALEdgeRight || edge == ALEdgeTrailing) { + // The bottom, right, and trailing insets (and relations, if an inequality) are inverted to become offsets + inset = -inset; + if (relation == NSLayoutRelationLessThanOrEqual) { + relation = NSLayoutRelationGreaterThanOrEqual; + } else if (relation == NSLayoutRelationGreaterThanOrEqual) { + relation = NSLayoutRelationLessThanOrEqual; + } + } + return [self autoPinEdge:edge toEdge:edge ofView:superview withOffset:inset relation:relation]; +} + +/** + Pins the edges of the view to the edges of its superview with the given edge insets. + The insets.left corresponds to a leading edge constraint, and insets.right corresponds to a trailing edge constraint. + + @param insets The insets for this view's edges from its superview's edges. + @return An array of constraints added. + */ +- (NSArray *)autoPinEdgesToSuperviewEdgesWithInsets:(ALEdgeInsets)insets +{ + NSMutableArray *constraints = [NSMutableArray new]; + [constraints addObject:[self autoPinEdgeToSuperviewEdge:ALEdgeTop withInset:insets.top]]; + [constraints addObject:[self autoPinEdgeToSuperviewEdge:ALEdgeLeading withInset:insets.left]]; + [constraints addObject:[self autoPinEdgeToSuperviewEdge:ALEdgeBottom withInset:insets.bottom]]; + [constraints addObject:[self autoPinEdgeToSuperviewEdge:ALEdgeTrailing withInset:insets.right]]; + return constraints; +} + +/** + Pins 3 of the 4 edges of the view to the edges of its superview with the given edge insets, excluding one edge. + The insets.left corresponds to a leading edge constraint, and insets.right corresponds to a trailing edge constraint. + + @param insets The insets for this view's edges from its superview's edges. The inset corresponding to the excluded edge + will be ignored. + @param edge The edge of this view to exclude in pinning to its superview; this method will not apply any constraint to it. + @return An array of constraints added. + */ +- (NSArray *)autoPinEdgesToSuperviewEdgesWithInsets:(ALEdgeInsets)insets excludingEdge:(ALEdge)edge +{ + NSMutableArray *constraints = [NSMutableArray new]; + if (edge != ALEdgeTop) { + [constraints addObject:[self autoPinEdgeToSuperviewEdge:ALEdgeTop withInset:insets.top]]; + } + if (edge != ALEdgeLeading && edge != ALEdgeLeft) { + [constraints addObject:[self autoPinEdgeToSuperviewEdge:ALEdgeLeading withInset:insets.left]]; + } + if (edge != ALEdgeBottom) { + [constraints addObject:[self autoPinEdgeToSuperviewEdge:ALEdgeBottom withInset:insets.bottom]]; + } + if (edge != ALEdgeTrailing && edge != ALEdgeRight) { + [constraints addObject:[self autoPinEdgeToSuperviewEdge:ALEdgeTrailing withInset:insets.right]]; + } + return constraints; +} + +#if __PureLayout_MinBaseSDK_iOS_8_0 + +/** + Pins the given edge of the view to the corresponding margin of its superview. + + @param edge The edge of this view to pin to the corresponding margin of its superview. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoPinEdgeToSuperviewMargin:(ALEdge)edge +{ + return [self autoPinEdgeToSuperviewMargin:edge relation:NSLayoutRelationEqual]; +} + +/** + Pins the given edge of the view to the corresponding margin of its superview as a maximum or minimum. + + @param edge The edge of this view to pin to the corresponding margin of its superview. + @param relation Whether the edge should be inset by at least, at most, or exactly the superview's margin. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoPinEdgeToSuperviewMargin:(ALEdge)edge relation:(NSLayoutRelation)relation +{ + self.translatesAutoresizingMaskIntoConstraints = NO; + ALView *superview = self.superview; + NSAssert(superview, @"View's superview must not be nil.\nView: %@", self); + if (edge == ALEdgeBottom || edge == ALEdgeRight || edge == ALEdgeTrailing) { + // The bottom, right, and trailing relations are inverted + if (relation == NSLayoutRelationLessThanOrEqual) { + relation = NSLayoutRelationGreaterThanOrEqual; + } else if (relation == NSLayoutRelationGreaterThanOrEqual) { + relation = NSLayoutRelationLessThanOrEqual; + } + } + ALMargin margin = [NSLayoutConstraint al_marginForEdge:edge]; + return [self autoConstrainAttribute:(ALAttribute)edge toAttribute:(ALAttribute)margin ofView:superview withOffset:0.0 relation:relation]; +} + +/** + Pins the edges of the view to the margins of its superview. + + @return An array of constraints added. + */ +- (NSArray *)autoPinEdgesToSuperviewMargins +{ + NSMutableArray *constraints = [NSMutableArray new]; + [constraints addObject:[self autoPinEdgeToSuperviewMargin:ALEdgeTop]]; + [constraints addObject:[self autoPinEdgeToSuperviewMargin:ALEdgeLeading]]; + [constraints addObject:[self autoPinEdgeToSuperviewMargin:ALEdgeBottom]]; + [constraints addObject:[self autoPinEdgeToSuperviewMargin:ALEdgeTrailing]]; + return constraints; +} + +/** + Pins 3 of the 4 edges of the view to the margins of its superview, excluding one edge. + + @param edge The edge of this view to exclude in pinning to its superview; this method will not apply any constraint to it. + @return An array of constraints added. + */ +- (NSArray *)autoPinEdgesToSuperviewMarginsExcludingEdge:(ALEdge)edge +{ + NSMutableArray *constraints = [NSMutableArray new]; + if (edge != ALEdgeTop) { + [constraints addObject:[self autoPinEdgeToSuperviewMargin:ALEdgeTop]]; + } + if (edge != ALEdgeLeading && edge != ALEdgeLeft) { + [constraints addObject:[self autoPinEdgeToSuperviewMargin:ALEdgeLeading]]; + } + if (edge != ALEdgeBottom) { + [constraints addObject:[self autoPinEdgeToSuperviewMargin:ALEdgeBottom]]; + } + if (edge != ALEdgeTrailing && edge != ALEdgeRight) { + [constraints addObject:[self autoPinEdgeToSuperviewMargin:ALEdgeTrailing]]; + } + return constraints; +} + +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 */ + + +#pragma mark Pin Edges + +/** + Pins an edge of the view to a given edge of another view. + + @param edge The edge of this view to pin. + @param toEdge The edge of the other view to pin to. + @param otherView The other view to pin to. Must be in the same view hierarchy as this view. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoPinEdge:(ALEdge)edge toEdge:(ALEdge)toEdge ofView:(ALView *)otherView +{ + return [self autoPinEdge:edge toEdge:toEdge ofView:otherView withOffset:0.0]; +} + +/** + Pins an edge of the view to a given edge of another view with an offset. + + @param edge The edge of this view to pin. + @param toEdge The edge of the other view to pin to. + @param otherView The other view to pin to. Must be in the same view hierarchy as this view. + @param offset The offset between the edge of this view and the edge of the other view. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoPinEdge:(ALEdge)edge toEdge:(ALEdge)toEdge ofView:(ALView *)otherView withOffset:(CGFloat)offset +{ + return [self autoPinEdge:edge toEdge:toEdge ofView:otherView withOffset:offset relation:NSLayoutRelationEqual]; +} + +/** + Pins an edge of the view to a given edge of another view with an offset as a maximum or minimum. + + @param edge The edge of this view to pin. + @param toEdge The edge of the other view to pin to. + @param otherView The other view to pin to. Must be in the same view hierarchy as this view. + @param offset The offset between the edge of this view and the edge of the other view. + @param relation Whether the offset should be at least, at most, or exactly equal to the given value. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoPinEdge:(ALEdge)edge toEdge:(ALEdge)toEdge ofView:(ALView *)otherView withOffset:(CGFloat)offset relation:(NSLayoutRelation)relation +{ + return [self autoConstrainAttribute:(ALAttribute)edge toAttribute:(ALAttribute)toEdge ofView:otherView withOffset:offset relation:relation]; +} + + +#pragma mark Align Axes + +/** + Aligns an axis of the view to the same axis of another view. + + @param axis The axis of this view and the other view to align. + @param otherView The other view to align to. Must be in the same view hierarchy as this view. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoAlignAxis:(ALAxis)axis toSameAxisOfView:(ALView *)otherView +{ + return [self autoAlignAxis:axis toSameAxisOfView:otherView withOffset:0.0]; +} + +/** + Aligns an axis of the view to the same axis of another view with an offset. + + @param axis The axis of this view and the other view to align. + @param otherView The other view to align to. Must be in the same view hierarchy as this view. + @param offset The offset between the axis of this view and the axis of the other view. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoAlignAxis:(ALAxis)axis toSameAxisOfView:(ALView *)otherView withOffset:(CGFloat)offset +{ + return [self autoConstrainAttribute:(ALAttribute)axis toAttribute:(ALAttribute)axis ofView:otherView withOffset:offset]; +} + + +#pragma mark Match Dimensions + +/** + Matches a dimension of the view to a given dimension of another view. + + @param dimension The dimension of this view to pin. + @param toDimension The dimension of the other view to pin to. + @param otherView The other view to match to. Must be in the same view hierarchy as this view. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoMatchDimension:(ALDimension)dimension toDimension:(ALDimension)toDimension ofView:(ALView *)otherView +{ + return [self autoMatchDimension:dimension toDimension:toDimension ofView:otherView withOffset:0.0]; +} + +/** + Matches a dimension of the view to a given dimension of another view with an offset. + + @param dimension The dimension of this view to pin. + @param toDimension The dimension of the other view to pin to. + @param otherView The other view to match to. Must be in the same view hierarchy as this view. + @param offset The offset between the dimension of this view and the dimension of the other view. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoMatchDimension:(ALDimension)dimension toDimension:(ALDimension)toDimension ofView:(ALView *)otherView withOffset:(CGFloat)offset +{ + return [self autoMatchDimension:dimension toDimension:toDimension ofView:otherView withOffset:offset relation:NSLayoutRelationEqual]; +} + +/** + Matches a dimension of the view to a given dimension of another view with an offset as a maximum or minimum. + + @param dimension The dimension of this view to pin. + @param toDimension The dimension of the other view to pin to. + @param otherView The other view to match to. Must be in the same view hierarchy as this view. + @param offset The offset between the dimension of this view and the dimension of the other view. + @param relation Whether the offset should be at least, at most, or exactly equal to the given value. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoMatchDimension:(ALDimension)dimension toDimension:(ALDimension)toDimension ofView:(ALView *)otherView withOffset:(CGFloat)offset relation:(NSLayoutRelation)relation +{ + return [self autoConstrainAttribute:(ALAttribute)dimension toAttribute:(ALAttribute)toDimension ofView:otherView withOffset:offset relation:relation]; +} + +/** + Matches a dimension of the view to a multiple of a given dimension of another view. + + @param dimension The dimension of this view to pin. + @param toDimension The dimension of the other view to pin to. + @param otherView The other view to match to. Must be in the same view hierarchy as this view. + @param multiplier The multiple of the other view's given dimension that this view's given dimension should be. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoMatchDimension:(ALDimension)dimension toDimension:(ALDimension)toDimension ofView:(ALView *)otherView withMultiplier:(CGFloat)multiplier +{ + return [self autoMatchDimension:dimension toDimension:toDimension ofView:otherView withMultiplier:multiplier relation:NSLayoutRelationEqual]; +} + +/** + Matches a dimension of the view to a multiple of a given dimension of another view as a maximum or minimum. + + @param dimension The dimension of this view to pin. + @param toDimension The dimension of the other view to pin to. + @param otherView The other view to match to. Must be in the same view hierarchy as this view. + @param multiplier The multiple of the other view's given dimension that this view's given dimension should be. + @param relation Whether the multiple should be at least, at most, or exactly equal to the given value. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoMatchDimension:(ALDimension)dimension toDimension:(ALDimension)toDimension ofView:(ALView *)otherView withMultiplier:(CGFloat)multiplier relation:(NSLayoutRelation)relation +{ + return [self autoConstrainAttribute:(ALAttribute)dimension toAttribute:(ALAttribute)toDimension ofView:otherView withMultiplier:multiplier relation:relation]; +} + + +#pragma mark Set Dimensions + +/** + Sets the view to a specific size. + + @param size The size to set this view's dimensions to. + @return An array of constraints added. + */ +- (NSArray *)autoSetDimensionsToSize:(CGSize)size +{ + NSMutableArray *constraints = [NSMutableArray new]; + [constraints addObject:[self autoSetDimension:ALDimensionWidth toSize:size.width]]; + [constraints addObject:[self autoSetDimension:ALDimensionHeight toSize:size.height]]; + return constraints; +} + +/** + Sets the given dimension of the view to a specific size. + + @param dimension The dimension of this view to set. + @param size The size to set the given dimension to. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoSetDimension:(ALDimension)dimension toSize:(CGFloat)size +{ + return [self autoSetDimension:dimension toSize:size relation:NSLayoutRelationEqual]; +} + +/** + Sets the given dimension of the view to a specific size as a maximum or minimum. + + @param dimension The dimension of this view to set. + @param size The size to set the given dimension to. + @param relation Whether the size should be at least, at most, or exactly equal to the given value. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoSetDimension:(ALDimension)dimension toSize:(CGFloat)size relation:(NSLayoutRelation)relation +{ + self.translatesAutoresizingMaskIntoConstraints = NO; + NSLayoutAttribute layoutAttribute = [NSLayoutConstraint al_layoutAttributeForAttribute:(ALAttribute)dimension]; + NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:self attribute:layoutAttribute relatedBy:relation toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:0.0 constant:size]; + [constraint autoInstall]; + return constraint; +} + + +#pragma mark Set Content Compression Resistance & Hugging + +/** + Sets the priority of content compression resistance for an axis. + NOTE: This method must be called from within the block passed into the method +[autoSetPriority:forConstraints:] + + @param axis The axis to set the content compression resistance priority for. + */ +- (void)autoSetContentCompressionResistancePriorityForAxis:(ALAxis)axis +{ + NSAssert([ALView al_isExecutingPriorityConstraintsBlock], @"%@ should only be called from within the block passed into the method +[autoSetPriority:forConstraints:]", NSStringFromSelector(_cmd)); + if ([ALView al_isExecutingPriorityConstraintsBlock]) { + self.translatesAutoresizingMaskIntoConstraints = NO; + ALLayoutConstraintAxis constraintAxis = [NSLayoutConstraint al_constraintAxisForAxis:axis]; +#if TARGET_OS_IPHONE + [self setContentCompressionResistancePriority:[ALView al_currentGlobalConstraintPriority] forAxis:constraintAxis]; +#else + [self setContentCompressionResistancePriority:[ALView al_currentGlobalConstraintPriority] forOrientation:constraintAxis]; +#endif /* TARGET_OS_IPHONE */ + } +} + +/** + Sets the priority of content hugging for an axis. + NOTE: This method must be called from within the block passed into the method +[autoSetPriority:forConstraints:] + + @param axis The axis to set the content hugging priority for. + */ +- (void)autoSetContentHuggingPriorityForAxis:(ALAxis)axis +{ + NSAssert([ALView al_isExecutingPriorityConstraintsBlock], @"%@ should only be called from within the block passed into the method +[autoSetPriority:forConstraints:]", NSStringFromSelector(_cmd)); + if ([ALView al_isExecutingPriorityConstraintsBlock]) { + self.translatesAutoresizingMaskIntoConstraints = NO; + ALLayoutConstraintAxis constraintAxis = [NSLayoutConstraint al_constraintAxisForAxis:axis]; +#if TARGET_OS_IPHONE + [self setContentHuggingPriority:[ALView al_currentGlobalConstraintPriority] forAxis:constraintAxis]; +#else + [self setContentHuggingPriority:[ALView al_currentGlobalConstraintPriority] forOrientation:constraintAxis]; +#endif /* TARGET_OS_IPHONE */ + } +} + + +#pragma mark Constrain Any Attributes + +/** + Constrains an attribute of the view to a given attribute of another view. + This method can be used to constrain different types of attributes across two views. + + @param attribute Any attribute of this view to constrain. + @param toAttribute Any attribute of the other view to constrain to. + @param otherView The other view to constrain to. Must be in the same view hierarchy as this view. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoConstrainAttribute:(ALAttribute)attribute toAttribute:(ALAttribute)toAttribute ofView:(ALView *)otherView +{ + return [self autoConstrainAttribute:attribute toAttribute:toAttribute ofView:otherView withOffset:0.0]; +} + +/** + Constrains an attribute of the view to a given attribute of another view with an offset. + This method can be used to constrain different types of attributes across two views. + + @param attribute Any attribute of this view to constrain. + @param toAttribute Any attribute of the other view to constrain to. + @param otherView The other view to constrain to. Must be in the same view hierarchy as this view. + @param offset The offset between the attribute of this view and the attribute of the other view. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoConstrainAttribute:(ALAttribute)attribute toAttribute:(ALAttribute)toAttribute ofView:(ALView *)otherView withOffset:(CGFloat)offset +{ + return [self autoConstrainAttribute:attribute toAttribute:toAttribute ofView:otherView withOffset:offset relation:NSLayoutRelationEqual]; +} + +/** + Constrains an attribute of the view to a given attribute of another view with an offset as a maximum or minimum. + This method can be used to constrain different types of attributes across two views. + + @param attribute Any attribute of this view to constrain. + @param toAttribute Any attribute of the other view to constrain to. + @param otherView The other view to constrain to. Must be in the same view hierarchy as this view. + @param offset The offset between the attribute of this view and the attribute of the other view. + @param relation Whether the offset should be at least, at most, or exactly equal to the given value. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoConstrainAttribute:(ALAttribute)attribute toAttribute:(ALAttribute)toAttribute ofView:(ALView *)otherView withOffset:(CGFloat)offset relation:(NSLayoutRelation)relation +{ + self.translatesAutoresizingMaskIntoConstraints = NO; + NSLayoutAttribute layoutAttribute = [NSLayoutConstraint al_layoutAttributeForAttribute:attribute]; + NSLayoutAttribute toLayoutAttribute = [NSLayoutConstraint al_layoutAttributeForAttribute:toAttribute]; + NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:self attribute:layoutAttribute relatedBy:relation toItem:otherView attribute:toLayoutAttribute multiplier:1.0 constant:offset]; + [constraint autoInstall]; + return constraint; +} + +/** + Constrains an attribute of the view to a given attribute of another view with a multiplier. + This method can be used to constrain different types of attributes across two views. + + @param attribute Any attribute of this view to constrain. + @param toAttribute Any attribute of the other view to constrain to. + @param otherView The other view to constrain to. Must be in the same view hierarchy as this view. + @param multiplier The multiplier between the attribute of this view and the attribute of the other view. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoConstrainAttribute:(ALAttribute)attribute toAttribute:(ALAttribute)toAttribute ofView:(ALView *)otherView withMultiplier:(CGFloat)multiplier +{ + return [self autoConstrainAttribute:attribute toAttribute:toAttribute ofView:otherView withMultiplier:multiplier relation:NSLayoutRelationEqual]; +} + +/** + Constrains an attribute of the view to a given attribute of another view with a multiplier as a maximum or minimum. + This method can be used to constrain different types of attributes across two views. + + @param attribute Any attribute of this view to constrain. + @param toAttribute Any attribute of the other view to constrain to. + @param otherView The other view to constrain to. Must be in the same view hierarchy as this view. + @param multiplier The multiplier between the attribute of this view and the attribute of the other view. + @param relation Whether the multiplier should be at least, at most, or exactly equal to the given value. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoConstrainAttribute:(ALAttribute)attribute toAttribute:(ALAttribute)toAttribute ofView:(ALView *)otherView withMultiplier:(CGFloat)multiplier relation:(NSLayoutRelation)relation +{ + self.translatesAutoresizingMaskIntoConstraints = NO; + NSLayoutAttribute layoutAttribute = [NSLayoutConstraint al_layoutAttributeForAttribute:attribute]; + NSLayoutAttribute toLayoutAttribute = [NSLayoutConstraint al_layoutAttributeForAttribute:toAttribute]; + NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:self attribute:layoutAttribute relatedBy:relation toItem:otherView attribute:toLayoutAttribute multiplier:multiplier constant:0.0]; + [constraint autoInstall]; + return constraint; +} + + +#pragma mark Pin to Layout Guides + +#if TARGET_OS_IPHONE + +/** + Pins the top edge of the view to the top layout guide of the given view controller with an inset. + For compatibility with iOS 6 (where layout guides do not exist), this method will simply pin the top edge of + the view to the top edge of the given view controller's view with an inset. + + @param viewController The view controller whose topLayoutGuide should be used to pin to. + @param inset The amount to inset this view's top edge from the layout guide. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoPinToTopLayoutGuideOfViewController:(UIViewController *)viewController withInset:(CGFloat)inset +{ + return [self autoPinToTopLayoutGuideOfViewController:viewController withInset:inset relation:NSLayoutRelationEqual]; +} + +- (NSLayoutConstraint *)autoPinToTopLayoutGuideOfViewController:(UIViewController *)viewController withInset:(CGFloat)inset relation:(NSLayoutRelation)relation +{ + if (__PureLayout_MinSysVer_iOS_7_0) { + self.translatesAutoresizingMaskIntoConstraints = NO; + NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeTop relatedBy:relation toItem:viewController.topLayoutGuide attribute:NSLayoutAttributeBottom multiplier:1.0 constant:inset]; + [viewController.view al_addConstraint:constraint]; // Can't use autoInstall because the layout guide is not a view + return constraint; + } else { + // iOS 6 fallback + return [self autoPinEdge:ALEdgeTop toEdge:ALEdgeTop ofView:viewController.view withOffset:inset relation:relation]; + } +} + +/** + Pins the bottom edge of the view to the bottom layout guide of the given view controller with an inset. + For compatibility with iOS 6 (where layout guides do not exist), this method will simply pin the bottom edge of + the view to the bottom edge of the given view controller's view with an inset. + + @param viewController The view controller whose bottomLayoutGuide should be used to pin to. + @param inset The amount to inset this view's bottom edge from the layout guide. + @return The constraint added. + */ +- (NSLayoutConstraint *)autoPinToBottomLayoutGuideOfViewController:(UIViewController *)viewController withInset:(CGFloat)inset +{ + return [self autoPinToBottomLayoutGuideOfViewController:viewController withInset:inset relation:NSLayoutRelationEqual]; +} + +- (NSLayoutConstraint *)autoPinToBottomLayoutGuideOfViewController:(UIViewController *)viewController withInset:(CGFloat)inset relation:(NSLayoutRelation)relation +{ + // The bottom inset (and relation, if an inequality) is inverted to become an offset + inset = -inset; + if (relation == NSLayoutRelationLessThanOrEqual) { + relation = NSLayoutRelationGreaterThanOrEqual; + } else if (relation == NSLayoutRelationGreaterThanOrEqual) { + relation = NSLayoutRelationLessThanOrEqual; + } + if (__PureLayout_MinSysVer_iOS_7_0) { + self.translatesAutoresizingMaskIntoConstraints = NO; + NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeBottom relatedBy:relation toItem:viewController.bottomLayoutGuide attribute:NSLayoutAttributeTop multiplier:1.0 constant:inset]; + [viewController.view al_addConstraint:constraint]; // Can't use autoInstall because the layout guide is not a view + return constraint; + } else { + // iOS 6 fallback + return [self autoPinEdge:ALEdgeBottom toEdge:ALEdgeBottom ofView:viewController.view withOffset:inset relation:relation]; + } +} + +#endif /* TARGET_OS_IPHONE */ + + +#pragma mark Deprecated Methods + +/** + DEPRECATED as of PureLayout v2.0.0. Retain a reference to and remove specific constraints instead, or recreate the view(s) entirely to remove all constraints. + Removes all explicit constraints that affect the view. + WARNING: Apple's constraint solver is not optimized for large-scale constraint removal; you may encounter major performance issues after using this method. + It is not recommended to use this method to "reset" a view for reuse in a different way with new constraints. Create a new view instead. + NOTE: This method preserves implicit constraints, such as intrinsic content size constraints, which you usually do not want to remove. + */ +- (void)autoRemoveConstraintsAffectingView +{ + [self autoRemoveConstraintsAffectingViewIncludingImplicitConstraints:NO]; +} + +/** + DEPRECATED as of PureLayout v2.0.0. Retain a reference to and remove specific constraints instead, or recreate the view(s) entirely to remove all constraints. + Removes all constraints that affect the view, optionally including implicit constraints. + WARNING: Apple's constraint solver is not optimized for large-scale constraint removal; you may encounter major performance issues after using this method. + It is not recommended to use this method to "reset" a view for reuse in a different way with new constraints. Create a new view instead. + NOTE: Implicit constraints are auto-generated lower priority constraints (such as those that attempt to keep a view at + its intrinsic content size by hugging its content & resisting compression), and you usually do not want to remove these. + + @param shouldRemoveImplicitConstraints Whether implicit constraints should be removed or skipped. + */ +- (void)autoRemoveConstraintsAffectingViewIncludingImplicitConstraints:(BOOL)shouldRemoveImplicitConstraints +{ + NSMutableArray *constraintsToRemove = [NSMutableArray new]; + ALView *startView = self; + do { + for (NSLayoutConstraint *constraint in startView.constraints) { + BOOL isImplicitConstraint = [NSStringFromClass([constraint class]) isEqualToString:@"NSContentSizeLayoutConstraint"]; + if (shouldRemoveImplicitConstraints || !isImplicitConstraint) { + if (constraint.firstItem == self || constraint.secondItem == self) { + [constraintsToRemove addObject:constraint]; + } + } + } + startView = startView.superview; + } while (startView); + [constraintsToRemove autoRemoveConstraints]; +} + +/** + DEPRECATED as of PureLayout v2.0.0. Retain a reference to and remove specific constraints instead, or recreate the view(s) entirely to remove all constraints. + Recursively removes all explicit constraints that affect the view and its subviews. + WARNING: Apple's constraint solver is not optimized for large-scale constraint removal; you may encounter major performance issues after using this method. + It is not recommended to use this method to "reset" views for reuse in a different way with new constraints. Create a new view instead. + NOTE: This method preserves implicit constraints, such as intrinsic content size constraints, which you usually do not want to remove. + */ +- (void)autoRemoveConstraintsAffectingViewAndSubviews +{ + [self autoRemoveConstraintsAffectingViewAndSubviewsIncludingImplicitConstraints:NO]; +} + +/** + DEPRECATED as of PureLayout v2.0.0. Retain a reference to and remove specific constraints instead, or recreate the view(s) entirely to remove all constraints. + Recursively removes all constraints that affect the view and its subviews, optionally including implicit constraints. + WARNING: Apple's constraint solver is not optimized for large-scale constraint removal; you may encounter major performance issues after using this method. + It is not recommended to use this method to "reset" views for reuse in a different way with new constraints. Create a new view instead. + NOTE: Implicit constraints are auto-generated lower priority constraints (such as those that attempt to keep a view at + its intrinsic content size by hugging its content & resisting compression), and you usually do not want to remove these. + + @param shouldRemoveImplicitConstraints Whether implicit constraints should be removed or skipped. + */ +- (void)autoRemoveConstraintsAffectingViewAndSubviewsIncludingImplicitConstraints:(BOOL)shouldRemoveImplicitConstraints +{ + [self autoRemoveConstraintsAffectingViewIncludingImplicitConstraints:shouldRemoveImplicitConstraints]; + for (ALView *subview in self.subviews) { + [subview autoRemoveConstraintsAffectingViewAndSubviewsIncludingImplicitConstraints:shouldRemoveImplicitConstraints]; + } +} + + +#pragma mark Internal Methods + +/** + Applies the global constraint priority and identifier to the given constraint. + This should be done before installing all constraints. + + @param constraint The constraint to set the global priority and identifier on. + */ ++ (void)al_applyGlobalStateToConstraint:(NSLayoutConstraint *)constraint +{ + if ([ALView al_isExecutingPriorityConstraintsBlock]) { + constraint.priority = [ALView al_currentGlobalConstraintPriority]; + } +#if __PureLayout_MinBaseSDK_iOS_8_0 + NSString *globalConstraintIdentifier = [ALView al_currentGlobalConstraintIdentifier]; + if (globalConstraintIdentifier) { + [constraint autoIdentify:globalConstraintIdentifier]; + } +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 */ +} + +/** + Adds the given constraint to this view after applying the global state to the constraint. + NOTE: This method is compatible with all versions of iOS, and should be used for older versions before the active + property on NSLayoutConstraint was introduced. + + This method should be the only one that calls the UIView/NSView addConstraint: method directly. + + @param constraint The constraint to set the global priority on and then add to this view. + */ +- (void)al_addConstraint:(NSLayoutConstraint *)constraint +{ + [ALView al_applyGlobalStateToConstraint:constraint]; + if ([ALView al_preventAutomaticConstraintInstallation]) { + [[ALView al_currentArrayOfCreatedConstraints] addObject:constraint]; + } else { + [self addConstraint:constraint]; + } +} + +/** + Returns the common superview for this view and the given other view. + Raises an exception if this view and the other view do not share a common superview. + + @return The common superview for the two views. + */ +- (ALView *)al_commonSuperviewWithView:(ALView *)otherView +{ + ALView *commonSuperview = nil; + ALView *startView = self; + do { +#if TARGET_OS_IPHONE + if ([otherView isDescendantOfView:startView]) { + commonSuperview = startView; + } +#else + if ([otherView isDescendantOf:startView]) { + commonSuperview = startView; + } +#endif /* TARGET_OS_IPHONE */ + startView = startView.superview; + } while (startView && !commonSuperview); + NSAssert(commonSuperview, @"Can't constrain two views that do not share a common superview. Make sure that both views have been added into the same view hierarchy."); + return commonSuperview; +} + +/** + Aligns this view to another view with an alignment attribute. + + @param attribute The attribute to use to align the two views. + @param otherView The other view to align to. + @param axis The axis along which the views are distributed, used to validate the alignment attribute. + @return The constraint added. + */ +- (NSLayoutConstraint *)al_alignAttribute:(ALAttribute)attribute toView:(ALView *)otherView forAxis:(ALAxis)axis +{ + NSLayoutConstraint *constraint = nil; + switch (attribute) { + case ALAttributeVertical: + NSAssert(axis == ALAxisVertical, @"Cannot align views that are distributed horizontally with ALAttributeVertical."); + constraint = [self autoAlignAxis:ALAxisVertical toSameAxisOfView:otherView]; + break; + case ALAttributeHorizontal: + NSAssert(axis != ALAxisVertical, @"Cannot align views that are distributed vertically with ALAttributeHorizontal."); + constraint = [self autoAlignAxis:ALAxisHorizontal toSameAxisOfView:otherView]; + break; + case ALAttributeBaseline: // same value as ALAttributeLastBaseline + NSAssert(axis != ALAxisVertical, @"Cannot align views that are distributed vertically with ALAttributeBaseline."); + constraint = [self autoAlignAxis:ALAxisBaseline toSameAxisOfView:otherView]; + break; +#if __PureLayout_MinBaseSDK_iOS_8_0 + case ALAttributeFirstBaseline: + NSAssert(__PureLayout_MinSysVer_iOS_8_0, @"ALAttributeFirstBaseline is only supported on iOS 8.0 or higher."); + NSAssert(axis != ALAxisVertical, @"Cannot align views that are distributed vertically with ALAttributeFirstBaseline."); + constraint = [self autoAlignAxis:ALAxisFirstBaseline toSameAxisOfView:otherView]; + break; +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 */ + case ALAttributeTop: + NSAssert(axis != ALAxisVertical, @"Cannot align views that are distributed vertically with ALAttributeTop."); + constraint = [self autoPinEdge:ALEdgeTop toEdge:ALEdgeTop ofView:otherView]; + break; + case ALAttributeLeft: + NSAssert(axis == ALAxisVertical, @"Cannot align views that are distributed horizontally with ALAttributeLeft."); + constraint = [self autoPinEdge:ALEdgeLeft toEdge:ALEdgeLeft ofView:otherView]; + break; + case ALAttributeBottom: + NSAssert(axis != ALAxisVertical, @"Cannot align views that are distributed vertically with ALAttributeBottom."); + constraint = [self autoPinEdge:ALEdgeBottom toEdge:ALEdgeBottom ofView:otherView]; + break; + case ALAttributeRight: + NSAssert(axis == ALAxisVertical, @"Cannot align views that are distributed horizontally with ALAttributeRight."); + constraint = [self autoPinEdge:ALEdgeRight toEdge:ALEdgeRight ofView:otherView]; + break; + case ALAttributeLeading: + NSAssert(axis == ALAxisVertical, @"Cannot align views that are distributed horizontally with ALAttributeLeading."); + constraint = [self autoPinEdge:ALEdgeLeading toEdge:ALEdgeLeading ofView:otherView]; + break; + case ALAttributeTrailing: + NSAssert(axis == ALAxisVertical, @"Cannot align views that are distributed horizontally with ALAttributeTrailing."); + constraint = [self autoPinEdge:ALEdgeTrailing toEdge:ALEdgeTrailing ofView:otherView]; + break; + + // All of the below attributes are invalid as alignment options. Listing them explicitly (even though they just fall through to the default case) to avoid an incomplete switch statement warning from the compiler. + case ALAttributeWidth: + case ALAttributeHeight: +#if __PureLayout_MinBaseSDK_iOS_8_0 + case ALAttributeMarginLeft: + case ALAttributeMarginRight: + case ALAttributeMarginTop: + case ALAttributeMarginBottom: + case ALAttributeMarginLeading: + case ALAttributeMarginTrailing: + case ALAttributeMarginAxisVertical: + case ALAttributeMarginAxisHorizontal: +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 */ + default: + NSAssert(nil, @"Unsupported attribute for alignment."); + break; + } + return constraint; +} + +@end diff --git a/Example/Pods/PureLayout/PureLayout/PureLayout/NSArray+PureLayout.h b/Example/Pods/PureLayout/PureLayout/PureLayout/NSArray+PureLayout.h new file mode 100755 index 0000000..10ece57 --- /dev/null +++ b/Example/Pods/PureLayout/PureLayout/PureLayout/NSArray+PureLayout.h @@ -0,0 +1,107 @@ +// +// NSArray+PureLayout.h +// v2.0.5 +// https://github.com/smileyborg/PureLayout +// +// Copyright (c) 2012 Richard Turton +// Copyright (c) 2013-2015 Tyler Fox +// +// This code is distributed under the terms and conditions of the MIT license. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +#import "PureLayoutDefines.h" + + +#pragma mark - NSArray+PureLayout + +/** + A category on NSArray that provides a simple yet powerful interface to: + - Manage an array of Auto Layout constraints + - Apply constraints to an array of views + */ +@interface NSArray (PureLayout) + + +#pragma mark Array of Constraints + +/** Activates the constraints in this array. */ +- (void)autoInstallConstraints; + +/** Deactivates the constraints in this array. */ +- (void)autoRemoveConstraints; + +#if __PureLayout_MinBaseSDK_iOS_8_0 + +/** Sets the string as the identifier for the constraints in this array. Available in iOS 7.0 and OS X 10.9 and later. */ +- (instancetype)autoIdentifyConstraints:(NSString *)identifier; + +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 */ + + +#pragma mark Array of Views + +/** Aligns views in this array to one another along a given edge. */ +- (NSArray *)autoAlignViewsToEdge:(ALEdge)edge; + +/** Aligns views in this array to one another along a given axis. */ +- (NSArray *)autoAlignViewsToAxis:(ALAxis)axis; + +/** Matches a given dimension of all the views in this array. */ +- (NSArray *)autoMatchViewsDimension:(ALDimension)dimension; + +/** Sets the given dimension of all the views in this array to a given size. */ +- (NSArray *)autoSetViewsDimension:(ALDimension)dimension toSize:(CGFloat)size; + +/** Sets all of the views in this array to a given size. */ +- (NSArray *)autoSetViewsDimensionsToSize:(CGSize)size; + + +/** Distributes the views in this array equally along the selected axis in their superview. Views will be the same size (variable) in the dimension along the axis and will have spacing (fixed) between them. */ +- (NSArray *)autoDistributeViewsAlongAxis:(ALAxis)axis + alignedTo:(ALAttribute)alignment + withFixedSpacing:(CGFloat)spacing; + +/** Distributes the views in this array equally along the selected axis in their superview. Views will be the same size (variable) in the dimension along the axis and will have spacing (fixed) between them, with optional insets from the first and last views to their superview. */ +- (NSArray *)autoDistributeViewsAlongAxis:(ALAxis)axis + alignedTo:(ALAttribute)alignment + withFixedSpacing:(CGFloat)spacing + insetSpacing:(BOOL)shouldSpaceInsets; + +/** Distributes the views in this array equally along the selected axis in their superview. Views will have spacing (fixed) between them, with optional insets from the first and last views to their superview, and optionally constrained to the same size in the dimension along the axis. */ +- (NSArray *)autoDistributeViewsAlongAxis:(ALAxis)axis + alignedTo:(ALAttribute)alignment + withFixedSpacing:(CGFloat)spacing + insetSpacing:(BOOL)shouldSpaceInsets + matchedSizes:(BOOL)shouldMatchSizes; + + +/** Distributes the views in this array equally along the selected axis in their superview. Views will be the same size (fixed) in the dimension along the axis and will have spacing (variable) between them. */ +- (NSArray *)autoDistributeViewsAlongAxis:(ALAxis)axis + alignedTo:(ALAttribute)alignment + withFixedSize:(CGFloat)size; + +/** Distributes the views in this array equally along the selected axis in their superview. Views will be the same size (fixed) in the dimension along the axis and will have spacing (variable) between them, with optional insets from the first and last views to their superview. */ +- (NSArray *)autoDistributeViewsAlongAxis:(ALAxis)axis + alignedTo:(ALAttribute)alignment + withFixedSize:(CGFloat)size + insetSpacing:(BOOL)shouldSpaceInsets; + +@end diff --git a/Example/Pods/PureLayout/PureLayout/PureLayout/NSArray+PureLayout.m b/Example/Pods/PureLayout/PureLayout/PureLayout/NSArray+PureLayout.m new file mode 100755 index 0000000..81c0fb5 --- /dev/null +++ b/Example/Pods/PureLayout/PureLayout/PureLayout/NSArray+PureLayout.m @@ -0,0 +1,506 @@ +// +// NSArray+PureLayout.m +// v2.0.5 +// https://github.com/smileyborg/PureLayout +// +// Copyright (c) 2012 Richard Turton +// Copyright (c) 2013-2015 Tyler Fox +// +// This code is distributed under the terms and conditions of the MIT license. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +#import "NSArray+PureLayout.h" +#import "ALView+PureLayout.h" +#import "NSLayoutConstraint+PureLayout.h" +#import "PureLayout+Internal.h" + + +#pragma mark - NSArray+PureLayout + +@implementation NSArray (PureLayout) + + +#pragma mark Array of Constraints + +/** + Activates the constraints in this array. + */ +- (void)autoInstallConstraints +{ +#if __PureLayout_MinBaseSDK_iOS_8_0 || __PureLayout_MinBaseSDK_OSX_10_10 + if ([NSLayoutConstraint respondsToSelector:@selector(activateConstraints:)]) { + for (id object in self) { + if ([object isKindOfClass:[NSLayoutConstraint class]]) { + [ALView al_applyGlobalStateToConstraint:object]; + } + } + if ([ALView al_preventAutomaticConstraintInstallation]) { + [[ALView al_currentArrayOfCreatedConstraints] addObjectsFromArray:self]; + } else { + [NSLayoutConstraint activateConstraints:self]; + } + return; + } +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 || __PureLayout_MinBaseSDK_OSX_10_10 */ + + for (id object in self) { + if ([object isKindOfClass:[NSLayoutConstraint class]]) { + [((NSLayoutConstraint *)object) autoInstall]; + } + } +} + +/** + Deactivates the constraints in this array. + */ +- (void)autoRemoveConstraints +{ +#if __PureLayout_MinBaseSDK_iOS_8_0 || __PureLayout_MinBaseSDK_OSX_10_10 + if ([NSLayoutConstraint respondsToSelector:@selector(deactivateConstraints:)]) { + [NSLayoutConstraint deactivateConstraints:self]; + return; + } +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 || __PureLayout_MinBaseSDK_OSX_10_10 */ + + for (id object in self) { + if ([object isKindOfClass:[NSLayoutConstraint class]]) { + [((NSLayoutConstraint *)object) autoRemove]; + } + } +} + +#if __PureLayout_MinBaseSDK_iOS_8_0 + +/** + Sets the string as the identifier for the constraints in this array. Available in iOS 7.0 and OS X 10.9 and later. + The identifier will be printed along with each constraint's description. + This is helpful to document the constraints' purpose and aid in debugging. + + @param identifier A string used to identify the constraints in this array. + @return This array. + */ +- (instancetype)autoIdentifyConstraints:(NSString *)identifier +{ + for (id object in self) { + if ([object isKindOfClass:[NSLayoutConstraint class]]) { + [((NSLayoutConstraint *)object) autoIdentify:identifier]; + } + } + return self; +} + +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 */ + + +#pragma mark Array of Views + +/** + Aligns views in this array to one another along a given edge. + Note: This array must contain at least 2 views, and all views must share a common superview. + + @param edge The edge to which the views will be aligned. + @return An array of constraints added. + */ +- (NSArray *)autoAlignViewsToEdge:(ALEdge)edge +{ + NSAssert([self al_containsMinimumNumberOfViews:2], @"This array must contain at least 2 views."); + NSMutableArray *constraints = [NSMutableArray new]; + ALView *previousView = nil; + for (id object in self) { + if ([object isKindOfClass:[ALView class]]) { + ALView *view = (ALView *)object; + view.translatesAutoresizingMaskIntoConstraints = NO; + if (previousView) { + [constraints addObject:[view autoPinEdge:edge toEdge:edge ofView:previousView]]; + } + previousView = view; + } + } + return constraints; +} + +/** + Aligns views in this array to one another along a given axis. + Note: This array must contain at least 2 views, and all views must share a common superview. + + @param axis The axis to which the views will be aligned. + @return An array of constraints added. + */ +- (NSArray *)autoAlignViewsToAxis:(ALAxis)axis +{ + NSAssert([self al_containsMinimumNumberOfViews:2], @"This array must contain at least 2 views."); + NSMutableArray *constraints = [NSMutableArray new]; + ALView *previousView = nil; + for (id object in self) { + if ([object isKindOfClass:[ALView class]]) { + ALView *view = (ALView *)object; + view.translatesAutoresizingMaskIntoConstraints = NO; + if (previousView) { + [constraints addObject:[view autoAlignAxis:axis toSameAxisOfView:previousView]]; + } + previousView = view; + } + } + return constraints; +} + +/** + Matches a given dimension of all the views in this array. + Note: This array must contain at least 2 views, and all views must share a common superview. + + @param dimension The dimension to match for all of the views. + @return An array of constraints added. + */ +- (NSArray *)autoMatchViewsDimension:(ALDimension)dimension +{ + NSAssert([self al_containsMinimumNumberOfViews:2], @"This array must contain at least 2 views."); + NSMutableArray *constraints = [NSMutableArray new]; + ALView *previousView = nil; + for (id object in self) { + if ([object isKindOfClass:[ALView class]]) { + ALView *view = (ALView *)object; + view.translatesAutoresizingMaskIntoConstraints = NO; + if (previousView) { + [constraints addObject:[view autoMatchDimension:dimension toDimension:dimension ofView:previousView]]; + } + previousView = view; + } + } + return constraints; +} + +/** + Sets the given dimension of all the views in this array to a given size. + Note: This array must contain at least 1 view. + + @param dimension The dimension of each of the views to set. + @param size The size to set the given dimension of each view to. + @return An array of constraints added. + */ +- (NSArray *)autoSetViewsDimension:(ALDimension)dimension toSize:(CGFloat)size +{ + NSAssert([self al_containsMinimumNumberOfViews:1], @"This array must contain at least 1 view."); + NSMutableArray *constraints = [NSMutableArray new]; + for (id object in self) { + if ([object isKindOfClass:[ALView class]]) { + ALView *view = (ALView *)object; + view.translatesAutoresizingMaskIntoConstraints = NO; + [constraints addObject:[view autoSetDimension:dimension toSize:size]]; + } + } + return constraints; +} + +/** + Sets all of the views in this array to a given size. + Note: This array must contain at least 1 view. + + @param size The size to set each view's dimensions to. + @return An array of constraints added. + */ +- (NSArray *)autoSetViewsDimensionsToSize:(CGSize)size +{ + NSMutableArray *constraints = [NSMutableArray new]; + [constraints addObjectsFromArray:[self autoSetViewsDimension:ALDimensionWidth toSize:size.width]]; + [constraints addObjectsFromArray:[self autoSetViewsDimension:ALDimensionHeight toSize:size.height]]; + return constraints; +} + + +/** + Distributes the views in this array equally along the selected axis in their superview. + Views will be the same size (variable) in the dimension along the axis and will have spacing (fixed) between them, + including from the first and last views to their superview. + + @param axis The axis along which to distribute the views. + @param alignment The attribute to use to align all the views to one another. + @param spacing The fixed amount of spacing between each view. + @return An array of constraints added. + */ +- (NSArray *)autoDistributeViewsAlongAxis:(ALAxis)axis + alignedTo:(ALAttribute)alignment + withFixedSpacing:(CGFloat)spacing +{ + return [self autoDistributeViewsAlongAxis:axis + alignedTo:alignment + withFixedSpacing:spacing + insetSpacing:YES]; +} + +/** + Distributes the views in this array equally along the selected axis in their superview. + Views will be the same size (variable) in the dimension along the axis and will have spacing (fixed) between them. + The first and last views can optionally be inset from their superview by the same amount of spacing as between views. + + @param axis The axis along which to distribute the views. + @param alignment The attribute to use to align all the views to one another. + @param spacing The fixed amount of spacing between each view. + @param shouldSpaceInsets Whether the first and last views should be equally inset from their superview. + @return An array of constraints added. + */ +- (NSArray *)autoDistributeViewsAlongAxis:(ALAxis)axis + alignedTo:(ALAttribute)alignment + withFixedSpacing:(CGFloat)spacing + insetSpacing:(BOOL)shouldSpaceInsets +{ + return [self autoDistributeViewsAlongAxis:axis + alignedTo:alignment + withFixedSpacing:spacing + insetSpacing:shouldSpaceInsets + matchedSizes:YES]; +} + +/** + Distributes the views in this array equally along the selected axis in their superview. + Views will have fixed spacing between them, and can optionally be constrained to the same size in the dimension along the axis. + The first and last views can optionally be inset from their superview by the same amount of spacing as between views. + + @param axis The axis along which to distribute the views. + @param alignment The attribute to use to align all the views to one another. + @param spacing The fixed amount of spacing between each view. + @param shouldSpaceInsets Whether the first and last views should be equally inset from their superview. + @param shouldMatchSizes Whether all views will be constrained to be the same size in the dimension along the axis. + NOTE: All views must specify an intrinsic content size if passing NO, otherwise the layout will be ambiguous! + @return An array of constraints added. + */ +- (NSArray *)autoDistributeViewsAlongAxis:(ALAxis)axis + alignedTo:(ALAttribute)alignment + withFixedSpacing:(CGFloat)spacing + insetSpacing:(BOOL)shouldSpaceInsets + matchedSizes:(BOOL)shouldMatchSizes +{ + NSAssert([self al_containsMinimumNumberOfViews:2], @"This array must contain at least 2 views to distribute."); + ALDimension matchedDimension; + ALEdge firstEdge, lastEdge; + switch (axis) { + case ALAxisHorizontal: + case ALAxisBaseline: // same value as ALAxisLastBaseline +#if __PureLayout_MinBaseSDK_iOS_8_0 + case ALAxisFirstBaseline: +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 */ + matchedDimension = ALDimensionWidth; + firstEdge = ALEdgeLeading; + lastEdge = ALEdgeTrailing; + break; + case ALAxisVertical: + matchedDimension = ALDimensionHeight; + firstEdge = ALEdgeTop; + lastEdge = ALEdgeBottom; + break; + default: + NSAssert(nil, @"Not a valid ALAxis."); + return nil; + } + CGFloat leadingSpacing = shouldSpaceInsets ? spacing : 0.0; + CGFloat trailingSpacing = shouldSpaceInsets ? spacing : 0.0; + + NSMutableArray *constraints = [NSMutableArray new]; + ALView *previousView = nil; + for (id object in self) { + if ([object isKindOfClass:[ALView class]]) { + ALView *view = (ALView *)object; + view.translatesAutoresizingMaskIntoConstraints = NO; + if (previousView) { + // Second, Third, ... View + [constraints addObject:[view autoPinEdge:firstEdge toEdge:lastEdge ofView:previousView withOffset:spacing]]; + if (shouldMatchSizes) { + [constraints addObject:[view autoMatchDimension:matchedDimension toDimension:matchedDimension ofView:previousView]]; + } + [constraints addObject:[view al_alignAttribute:alignment toView:previousView forAxis:axis]]; + } + else { + // First view + [constraints addObject:[view autoPinEdgeToSuperviewEdge:firstEdge withInset:leadingSpacing]]; + } + previousView = view; + } + } + if (previousView) { + // Last View + [constraints addObject:[previousView autoPinEdgeToSuperviewEdge:lastEdge withInset:trailingSpacing]]; + } + return constraints; +} + +/** + Distributes the views in this array equally along the selected axis in their superview. + Views will be the same size (fixed) in the dimension along the axis and will have spacing (variable) between them, + including from the first and last views to their superview. + + @param axis The axis along which to distribute the views. + @param alignment The attribute to use to align all the views to one another. + @param size The fixed size of each view in the dimension along the given axis. + @return An array of constraints added. + */ +- (NSArray *)autoDistributeViewsAlongAxis:(ALAxis)axis + alignedTo:(ALAttribute)alignment + withFixedSize:(CGFloat)size +{ + return [self autoDistributeViewsAlongAxis:axis + alignedTo:alignment + withFixedSize:size + insetSpacing:YES]; +} + +/** + Distributes the views in this array equally along the selected axis in their superview. + Views will be the same size (fixed) in the dimension along the axis and will have spacing (variable) between them. + The first and last views can optionally be inset from their superview by the same amount of spacing as between views. + + @param axis The axis along which to distribute the views. + @param alignment The attribute to use to align all the views to one another. + @param size The fixed size of each view in the dimension along the given axis. + @param shouldSpaceInsets Whether the first and last views should be equally inset from their superview. + @return An array of constraints added. + */ +- (NSArray *)autoDistributeViewsAlongAxis:(ALAxis)axis + alignedTo:(ALAttribute)alignment + withFixedSize:(CGFloat)size + insetSpacing:(BOOL)shouldSpaceInsets +{ + NSAssert([self al_containsMinimumNumberOfViews:2], @"This array must contain at least 2 views to distribute."); + ALDimension fixedDimension; + NSLayoutAttribute attribute; + switch (axis) { + case ALAxisHorizontal: + case ALAxisBaseline: // same value as ALAxisLastBaseline +#if __PureLayout_MinBaseSDK_iOS_8_0 + case ALAxisFirstBaseline: +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 */ + fixedDimension = ALDimensionWidth; + attribute = NSLayoutAttributeCenterX; + break; + case ALAxisVertical: + fixedDimension = ALDimensionHeight; + attribute = NSLayoutAttributeCenterY; + break; + default: + NSAssert(nil, @"Not a valid ALAxis."); + return nil; + } +#if TARGET_OS_IPHONE +# if !defined(PURELAYOUT_APP_EXTENSIONS) + BOOL isRightToLeftLayout = [[UIApplication sharedApplication] userInterfaceLayoutDirection] == UIUserInterfaceLayoutDirectionRightToLeft; +# else + // App Extensions may not access -[UIApplication sharedApplication]; fall back to checking the bundle's preferred localization character direction + BOOL isRightToLeftLayout = [NSLocale characterDirectionForLanguage:[[NSBundle mainBundle] preferredLocalizations][0]] == NSLocaleLanguageDirectionRightToLeft; +# endif /* !defined(PURELAYOUT_APP_EXTENSIONS) */ +#else + BOOL isRightToLeftLayout = [[NSApplication sharedApplication] userInterfaceLayoutDirection] == NSUserInterfaceLayoutDirectionRightToLeft; +#endif /* TARGET_OS_IPHONE */ + BOOL shouldFlipOrder = isRightToLeftLayout && (axis != ALAxisVertical); // imitate the effect of leading/trailing when distributing horizontally + + NSMutableArray *constraints = [NSMutableArray new]; + NSArray *views = [self al_copyViewsOnly]; + NSUInteger numberOfViews = [views count]; + ALView *commonSuperview = [views al_commonSuperviewOfViews]; + ALView *previousView = nil; + for (NSUInteger i = 0; i < numberOfViews; i++) { + ALView *view = shouldFlipOrder ? views[numberOfViews - i - 1] : views[i]; + view.translatesAutoresizingMaskIntoConstraints = NO; + [constraints addObject:[view autoSetDimension:fixedDimension toSize:size]]; + CGFloat multiplier, constant; + if (shouldSpaceInsets) { + multiplier = (i * 2.0 + 2.0) / (numberOfViews + 1.0); + constant = (multiplier - 1.0) * size / 2.0; + } else { + multiplier = (i * 2.0) / (numberOfViews - 1.0); + constant = (-multiplier + 1.0) * size / 2.0; + } + // If the multiplier is very close to 0, set it to the minimum value to prevent the second item in the constraint from being lost. Filed as rdar://19168380 + if (fabs(multiplier) < kMULTIPLIER_MIN_VALUE) { + multiplier = kMULTIPLIER_MIN_VALUE; + } + NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:view attribute:attribute relatedBy:NSLayoutRelationEqual toItem:commonSuperview attribute:attribute multiplier:multiplier constant:constant]; + [constraint autoInstall]; + [constraints addObject:constraint]; + if (previousView) { + [constraints addObject:[view al_alignAttribute:alignment toView:previousView forAxis:axis]]; + } + previousView = view; + } + return constraints; +} + +#pragma mark Internal Helper Methods + +/** + Returns the common superview for the views in this array. + Raises an exception if the views in this array do not share a common superview. + + @return The common superview for the views in this array. + */ +- (ALView *)al_commonSuperviewOfViews +{ + ALView *commonSuperview = nil; + ALView *previousView = nil; + for (id object in self) { + if ([object isKindOfClass:[ALView class]]) { + ALView *view = (ALView *)object; + if (previousView) { + commonSuperview = [view al_commonSuperviewWithView:commonSuperview]; + } else { + commonSuperview = view; + } + previousView = view; + } + } + NSAssert(commonSuperview, @"Can't constrain views that do not share a common superview. Make sure that all the views in this array have been added into the same view hierarchy."); + return commonSuperview; +} + +/** + Determines whether this array contains a minimum number of views. + + @param minimumNumberOfViews The minimum number of views to check for. + @return YES if this array contains at least the minimum number of views, NO otherwise. + */ +- (BOOL)al_containsMinimumNumberOfViews:(NSUInteger)minimumNumberOfViews +{ + NSUInteger numberOfViews = 0; + for (id object in self) { + if ([object isKindOfClass:[ALView class]]) { + numberOfViews++; + if (numberOfViews >= minimumNumberOfViews) { + return YES; + } + } + } + return numberOfViews >= minimumNumberOfViews; +} + +/** + Creates a copy of this array containing only the view objects in it. + + @return A new array containing only the views that are in this array. + */ +- (NSArray *)al_copyViewsOnly +{ + NSMutableArray *viewsOnlyArray = [NSMutableArray arrayWithCapacity:[self count]]; + for (id object in self) { + if ([object isKindOfClass:[ALView class]]) { + [viewsOnlyArray addObject:object]; + } + } + return viewsOnlyArray; +} + +@end diff --git a/Example/Pods/PureLayout/PureLayout/PureLayout/NSLayoutConstraint+PureLayout.h b/Example/Pods/PureLayout/PureLayout/PureLayout/NSLayoutConstraint+PureLayout.h new file mode 100755 index 0000000..87797f6 --- /dev/null +++ b/Example/Pods/PureLayout/PureLayout/PureLayout/NSLayoutConstraint+PureLayout.h @@ -0,0 +1,58 @@ +// +// NSLayoutConstraint+PureLayout.h +// v2.0.5 +// https://github.com/smileyborg/PureLayout +// +// Copyright (c) 2013-2015 Tyler Fox +// +// This code is distributed under the terms and conditions of the MIT license. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +#import "PureLayoutDefines.h" + + +#pragma mark - NSLayoutConstraint+PureLayout + +/** + A category on NSLayoutConstraint that allows constraints to be easily installed & removed. + */ +@interface NSLayoutConstraint (PureLayout) + + +#pragma mark Install & Remove Constraints + +/** Activates the the constraint. */ +- (void)autoInstall; + +/** Deactivates the constraint. */ +- (void)autoRemove; + + +#pragma mark Identify Constraints + +#if __PureLayout_MinBaseSDK_iOS_8_0 || __PureLayout_MinBaseSDK_OSX_10_10 + +/** Sets the string as the identifier for this constraint. Available in iOS 7.0 and OS X 10.9 and later. */ +- (instancetype)autoIdentify:(NSString *)identifier; + +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 || __PureLayout_MinBaseSDK_OSX_10_10 */ + +@end diff --git a/Example/Pods/PureLayout/PureLayout/PureLayout/NSLayoutConstraint+PureLayout.m b/Example/Pods/PureLayout/PureLayout/PureLayout/NSLayoutConstraint+PureLayout.m new file mode 100755 index 0000000..1a290b5 --- /dev/null +++ b/Example/Pods/PureLayout/PureLayout/PureLayout/NSLayoutConstraint+PureLayout.m @@ -0,0 +1,314 @@ +// +// NSLayoutConstraint+PureLayout.m +// v2.0.5 +// https://github.com/smileyborg/PureLayout +// +// Copyright (c) 2013-2015 Tyler Fox +// +// This code is distributed under the terms and conditions of the MIT license. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +#import "NSLayoutConstraint+PureLayout.h" +#import "ALView+PureLayout.h" +#import "PureLayout+Internal.h" + + +#pragma mark - NSLayoutConstraint+PureLayout + +@implementation NSLayoutConstraint (PureLayout) + + +#pragma mark Installing & Removing Constraints + +/** + Activates the constraint. + */ +- (void)autoInstall +{ +#if __PureLayout_MinBaseSDK_iOS_8_0 || __PureLayout_MinBaseSDK_OSX_10_10 + if ([self respondsToSelector:@selector(setActive:)]) { + [ALView al_applyGlobalStateToConstraint:self]; + if ([ALView al_preventAutomaticConstraintInstallation]) { + [[ALView al_currentArrayOfCreatedConstraints] addObject:self]; + } else { + self.active = YES; + } + return; + } +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 || __PureLayout_MinBaseSDK_OSX_10_10 */ + + NSAssert(self.firstItem || self.secondItem, @"Can't install a constraint with nil firstItem and secondItem."); + if (self.firstItem) { + if (self.secondItem) { + NSAssert([self.firstItem isKindOfClass:[ALView class]] && [self.secondItem isKindOfClass:[ALView class]], @"Can only automatically install a constraint if both items are views."); + ALView *commonSuperview = [self.firstItem al_commonSuperviewWithView:self.secondItem]; + [commonSuperview al_addConstraint:self]; + } else { + NSAssert([self.firstItem isKindOfClass:[ALView class]], @"Can only automatically install a constraint if the item is a view."); + [self.firstItem al_addConstraint:self]; + } + } else { + NSAssert([self.secondItem isKindOfClass:[ALView class]], @"Can only automatically install a constraint if the item is a view."); + [self.secondItem al_addConstraint:self]; + } +} + +/** + Deactivates the constraint. + */ +- (void)autoRemove +{ +#if __PureLayout_MinBaseSDK_iOS_8_0 || __PureLayout_MinBaseSDK_OSX_10_10 + if ([self respondsToSelector:@selector(setActive:)]) { + self.active = NO; + return; + } +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 || __PureLayout_MinBaseSDK_OSX_10_10 */ + + if (self.secondItem) { + ALView *commonSuperview = [self.firstItem al_commonSuperviewWithView:self.secondItem]; + while (commonSuperview) { + if ([commonSuperview.constraints containsObject:self]) { + [commonSuperview removeConstraint:self]; + return; + } + commonSuperview = commonSuperview.superview; + } + } + else { + [self.firstItem removeConstraint:self]; + return; + } + NSAssert(nil, @"Failed to remove constraint: %@", self); +} + + +#pragma mark Identify Constraints + +#if __PureLayout_MinBaseSDK_iOS_8_0 || __PureLayout_MinBaseSDK_OSX_10_10 + +/** + Sets the string as the identifier for this constraint. Available in iOS 7.0 and OS X 10.9 and later. + The identifier will be printed along with the constraint's description. + This is helpful to document a constraint's purpose and aid in debugging. + + @param identifier A string used to identify this constraint. + @return This constraint. + */ +- (instancetype)autoIdentify:(NSString *)identifier +{ + if ([self respondsToSelector:@selector(setIdentifier:)]) { + self.identifier = identifier; + } + return self; +} + +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 || __PureLayout_MinBaseSDK_OSX_10_10 */ + + +#pragma mark Internal Methods + +/** + Returns the corresponding NSLayoutAttribute for the given ALAttribute. + + @return The layout attribute for the given ALAttribute. + */ ++ (NSLayoutAttribute)al_layoutAttributeForAttribute:(ALAttribute)attribute +{ + NSLayoutAttribute layoutAttribute = NSLayoutAttributeNotAnAttribute; + switch (attribute) { + case ALEdgeLeft: + layoutAttribute = NSLayoutAttributeLeft; + break; + case ALEdgeRight: + layoutAttribute = NSLayoutAttributeRight; + break; + case ALEdgeTop: + layoutAttribute = NSLayoutAttributeTop; + break; + case ALEdgeBottom: + layoutAttribute = NSLayoutAttributeBottom; + break; + case ALEdgeLeading: + layoutAttribute = NSLayoutAttributeLeading; + break; + case ALEdgeTrailing: + layoutAttribute = NSLayoutAttributeTrailing; + break; + case ALDimensionWidth: + layoutAttribute = NSLayoutAttributeWidth; + break; + case ALDimensionHeight: + layoutAttribute = NSLayoutAttributeHeight; + break; + case ALAxisVertical: + layoutAttribute = NSLayoutAttributeCenterX; + break; + case ALAxisHorizontal: + layoutAttribute = NSLayoutAttributeCenterY; + break; + case ALAxisBaseline: // same value as ALAxisLastBaseline + layoutAttribute = NSLayoutAttributeBaseline; + break; +#if __PureLayout_MinBaseSDK_iOS_8_0 + case ALAxisFirstBaseline: + NSAssert(__PureLayout_MinSysVer_iOS_8_0, @"ALAxisFirstBaseline is only supported on iOS 8.0 or higher."); + layoutAttribute = NSLayoutAttributeFirstBaseline; + break; + case ALMarginLeft: + NSAssert(__PureLayout_MinSysVer_iOS_8_0, @"ALEdgeLeftMargin is only supported on iOS 8.0 or higher."); + layoutAttribute = NSLayoutAttributeLeftMargin; + break; + case ALMarginRight: + NSAssert(__PureLayout_MinSysVer_iOS_8_0, @"ALEdgeRightMargin is only supported on iOS 8.0 or higher."); + layoutAttribute = NSLayoutAttributeRightMargin; + break; + case ALMarginTop: + NSAssert(__PureLayout_MinSysVer_iOS_8_0, @"ALEdgeTopMargin is only supported on iOS 8.0 or higher."); + layoutAttribute = NSLayoutAttributeTopMargin; + break; + case ALMarginBottom: + NSAssert(__PureLayout_MinSysVer_iOS_8_0, @"ALEdgeBottomMargin is only supported on iOS 8.0 or higher."); + layoutAttribute = NSLayoutAttributeBottomMargin; + break; + case ALMarginLeading: + NSAssert(__PureLayout_MinSysVer_iOS_8_0, @"ALEdgeLeadingMargin is only supported on iOS 8.0 or higher."); + layoutAttribute = NSLayoutAttributeLeadingMargin; + break; + case ALMarginTrailing: + NSAssert(__PureLayout_MinSysVer_iOS_8_0, @"ALEdgeTrailingMargin is only supported on iOS 8.0 or higher."); + layoutAttribute = NSLayoutAttributeTrailingMargin; + break; + case ALMarginAxisVertical: + NSAssert(__PureLayout_MinSysVer_iOS_8_0, @"ALAxisVerticalMargin is only supported on iOS 8.0 or higher."); + layoutAttribute = NSLayoutAttributeCenterXWithinMargins; + break; + case ALMarginAxisHorizontal: + NSAssert(__PureLayout_MinSysVer_iOS_8_0, @"ALAxisHorizontalMargin is only supported on iOS 8.0 or higher."); + layoutAttribute = NSLayoutAttributeCenterYWithinMargins; + break; +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 */ + default: + NSAssert(nil, @"Not a valid ALAttribute."); + break; + } + return layoutAttribute; +} + +/** + Returns the corresponding ALLayoutConstraintAxis for the given ALAxis. + + @return The constraint axis for the given axis. + */ ++ (ALLayoutConstraintAxis)al_constraintAxisForAxis:(ALAxis)axis +{ + ALLayoutConstraintAxis constraintAxis; + switch (axis) { + case ALAxisVertical: + constraintAxis = ALLayoutConstraintAxisVertical; + break; + case ALAxisHorizontal: + case ALAxisBaseline: // same value as ALAxisLastBaseline +#if __PureLayout_MinBaseSDK_iOS_8_0 + case ALAxisFirstBaseline: +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 */ + constraintAxis = ALLayoutConstraintAxisHorizontal; + break; + default: + NSAssert(nil, @"Not a valid ALAxis."); + constraintAxis = ALLayoutConstraintAxisHorizontal; // default to a random value to satisfy the compiler + break; + } + return constraintAxis; +} + +#if __PureLayout_MinBaseSDK_iOS_8_0 + +/** + Returns the corresponding margin for the given edge. + + @param edge The edge to convert to the corresponding margin. + @return The margin for the given edge. + */ ++ (ALMargin)al_marginForEdge:(ALEdge)edge +{ + NSAssert(__PureLayout_MinSysVer_iOS_8_0, @"Margin attributes are only supported on iOS 8.0 or higher."); + ALMargin margin; + switch (edge) { + case ALEdgeLeft: + margin = ALMarginLeft; + break; + case ALEdgeRight: + margin = ALMarginRight; + break; + case ALEdgeTop: + margin = ALMarginTop; + break; + case ALEdgeBottom: + margin = ALMarginBottom; + break; + case ALEdgeLeading: + margin = ALMarginLeading; + break; + case ALEdgeTrailing: + margin = ALMarginTrailing; + break; + default: + NSAssert(nil, @"Not a valid ALEdge."); + margin = ALMarginLeft; // default to a random value to satisfy the compiler + break; + } + return margin; +} + +/** + Returns the corresponding margin axis for the given axis. + + @param axis The axis to convert to the corresponding margin axis. + @return The margin axis for the given axis. + */ ++ (ALMarginAxis)al_marginAxisForAxis:(ALAxis)axis +{ + NSAssert(__PureLayout_MinSysVer_iOS_8_0, @"Margin attributes are only supported on iOS 8.0 or higher."); + ALMarginAxis marginAxis; + switch (axis) { + case ALAxisVertical: + marginAxis = ALMarginAxisVertical; + break; + case ALAxisHorizontal: + marginAxis = ALMarginAxisHorizontal; + break; + case ALAxisBaseline: + case ALAxisFirstBaseline: + NSAssert(nil, @"The baseline axis attributes do not have corresponding margin axis attributes."); + marginAxis = ALMarginAxisVertical; // default to a random value to satisfy the compiler + break; + default: + NSAssert(nil, @"Not a valid ALAxis."); + marginAxis = ALMarginAxisVertical; // default to a random value to satisfy the compiler + break; + } + return marginAxis; +} + +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 */ + +@end diff --git a/Example/Pods/PureLayout/PureLayout/PureLayout/PureLayout+Internal.h b/Example/Pods/PureLayout/PureLayout/PureLayout/PureLayout+Internal.h new file mode 100644 index 0000000..28fbfcf --- /dev/null +++ b/Example/Pods/PureLayout/PureLayout/PureLayout/PureLayout+Internal.h @@ -0,0 +1,78 @@ +// +// PureLayout+Internal.h +// v2.0.5 +// https://github.com/smileyborg/PureLayout +// +// Copyright (c) 2014-2015 Tyler Fox +// +// This code is distributed under the terms and conditions of the MIT license. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +#import "PureLayoutDefines.h" + +/** A constant that represents the smallest valid positive value for the multiplier of a constraint, + since a value of 0 will cause the second item to be lost in the internal auto layout engine. */ +static const CGFloat kMULTIPLIER_MIN_VALUE = 0.00001; // very small floating point numbers (e.g. CGFLOAT_MIN) can cause problems + + +/** + A category that exposes the internal (private) helper methods of the ALView+PureLayout category. + */ +@interface ALView (PureLayoutInternal) + ++ (BOOL)al_preventAutomaticConstraintInstallation; ++ (NSMutableArray *)al_currentArrayOfCreatedConstraints; ++ (BOOL)al_isExecutingPriorityConstraintsBlock; ++ (ALLayoutPriority)al_currentGlobalConstraintPriority; ++ (NSString *)al_currentGlobalConstraintIdentifier; ++ (void)al_applyGlobalStateToConstraint:(NSLayoutConstraint *)constraint; +- (void)al_addConstraint:(NSLayoutConstraint *)constraint; +- (ALView *)al_commonSuperviewWithView:(ALView *)otherView; +- (NSLayoutConstraint *)al_alignAttribute:(ALAttribute)attribute toView:(ALView *)otherView forAxis:(ALAxis)axis; + +@end + + +/** + A category that exposes the internal (private) helper methods of the NSArray+PureLayout category. + */ +@interface NSArray (PureLayoutInternal) + +- (ALView *)al_commonSuperviewOfViews; +- (BOOL)al_containsMinimumNumberOfViews:(NSUInteger)minimumNumberOfViews; +- (NSArray *)al_copyViewsOnly; + +@end + + +/** + A category that exposes the internal (private) helper methods of the NSLayoutConstraint+PureLayout category. + */ +@interface NSLayoutConstraint (PureLayoutInternal) + ++ (NSLayoutAttribute)al_layoutAttributeForAttribute:(ALAttribute)attribute; ++ (ALLayoutConstraintAxis)al_constraintAxisForAxis:(ALAxis)axis; +#if __PureLayout_MinBaseSDK_iOS_8_0 ++ (ALMargin)al_marginForEdge:(ALEdge)edge; ++ (ALMarginAxis)al_marginAxisForAxis:(ALAxis)axis; +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 */ + +@end diff --git a/Example/Pods/PureLayout/PureLayout/PureLayout/PureLayout.h b/Example/Pods/PureLayout/PureLayout/PureLayout/PureLayout.h new file mode 100755 index 0000000..8c47775 --- /dev/null +++ b/Example/Pods/PureLayout/PureLayout/PureLayout/PureLayout.h @@ -0,0 +1,36 @@ +// +// PureLayout.h +// v2.0.5 +// https://github.com/smileyborg/PureLayout +// +// Copyright (c) 2014-2015 Tyler Fox +// +// This code is distributed under the terms and conditions of the MIT license. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +#ifndef PureLayout_h +#define PureLayout_h + +#import "ALView+PureLayout.h" +#import "NSArray+PureLayout.h" +#import "NSLayoutConstraint+PureLayout.h" + +#endif /* PureLayout_h */ diff --git a/Example/Pods/PureLayout/PureLayout/PureLayout/PureLayoutDefines.h b/Example/Pods/PureLayout/PureLayout/PureLayout/PureLayoutDefines.h new file mode 100755 index 0000000..5b0f0bb --- /dev/null +++ b/Example/Pods/PureLayout/PureLayout/PureLayout/PureLayoutDefines.h @@ -0,0 +1,206 @@ +// +// PureLayoutDefines.h +// v2.0.5 +// https://github.com/smileyborg/PureLayout +// +// Copyright (c) 2014-2015 Tyler Fox +// +// This code is distributed under the terms and conditions of the MIT license. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +#ifndef PureLayoutDefines_h +#define PureLayoutDefines_h + +#import + +// Define some preprocessor macros to check for a minimum Base SDK. These are used to prevent compile-time errors in older versions of Xcode. +#define __PureLayout_MinBaseSDK_iOS_8_0 (TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_7_1) +#define __PureLayout_MinBaseSDK_OSX_10_10 (!TARGET_OS_IPHONE && __MAC_OS_X_VERSION_MAX_ALLOWED > __MAC_10_9) + +// Define some preprocessor macros to check for a minimum System Version. These are used to prevent runtime crashes on older versions of iOS/OS X. +#define __PureLayout_MinSysVer_iOS_7_0 (TARGET_OS_IPHONE && floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) +#define __PureLayout_MinSysVer_iOS_8_0 (TARGET_OS_IPHONE && floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_7_1) +#define __PureLayout_MinSysVer_OSX_10_9 (!TARGET_OS_IPHONE && floor(NSFoundationVersionNumber) > NSFoundationVersionNumber10_8_4) + +// Define generic AL-prefixed macros for the types/constants/etc that have slight naming variations across iOS and OS X, which allows the same code to be platform-independent +#if TARGET_OS_IPHONE +# import +# define ALView UIView +# define ALEdgeInsets UIEdgeInsets +# define ALEdgeInsetsZero UIEdgeInsetsZero +# define ALEdgeInsetsMake UIEdgeInsetsMake +# define ALLayoutConstraintAxis UILayoutConstraintAxis +# define ALLayoutConstraintOrientation ALLayoutConstraintAxis +# define ALLayoutConstraintAxisHorizontal UILayoutConstraintAxisHorizontal +# define ALLayoutConstraintAxisVertical UILayoutConstraintAxisVertical +# define ALLayoutConstraintOrientationHorizontal ALLayoutConstraintAxisHorizontal +# define ALLayoutConstraintOrientationVertical ALLayoutConstraintAxisVertical +# define ALLayoutPriority UILayoutPriority +# define ALLayoutPriorityRequired UILayoutPriorityRequired +# define ALLayoutPriorityDefaultHigh UILayoutPriorityDefaultHigh +# define ALLayoutPriorityDefaultLow UILayoutPriorityDefaultLow +# define ALLayoutPriorityFittingSizeLevel UILayoutPriorityFittingSizeLevel +# define ALLayoutPriorityFittingSizeCompression ALLayoutPriorityFittingSizeLevel +#else +# import +# define ALView NSView +# define ALEdgeInsets NSEdgeInsets +# define ALEdgeInsetsZero NSEdgeInsetsMake(0, 0, 0, 0) +# define ALEdgeInsetsMake NSEdgeInsetsMake +# define ALLayoutConstraintOrientation NSLayoutConstraintOrientation +# define ALLayoutConstraintAxis ALLayoutConstraintOrientation +# define ALLayoutConstraintOrientationHorizontal NSLayoutConstraintOrientationHorizontal +# define ALLayoutConstraintOrientationVertical NSLayoutConstraintOrientationVertical +# define ALLayoutConstraintAxisHorizontal ALLayoutConstraintOrientationHorizontal +# define ALLayoutConstraintAxisVertical ALLayoutConstraintOrientationVertical +# define ALLayoutPriority NSLayoutPriority +# define ALLayoutPriorityRequired NSLayoutPriorityRequired +# define ALLayoutPriorityDefaultHigh NSLayoutPriorityDefaultHigh +# define ALLayoutPriorityDefaultLow NSLayoutPriorityDefaultLow +# define ALLayoutPriorityFittingSizeCompression NSLayoutPriorityFittingSizeCompression +# define ALLayoutPriorityFittingSizeLevel ALLayoutPriorityFittingSizeCompression +#endif /* TARGET_OS_IPHONE */ + + +#pragma mark PureLayout Attributes + +/** Constants that represent edges of a view. */ +typedef NS_ENUM(NSInteger, ALEdge) { + /** The left edge of the view. */ + ALEdgeLeft = NSLayoutAttributeLeft, + /** The right edge of the view. */ + ALEdgeRight = NSLayoutAttributeRight, + /** The top edge of the view. */ + ALEdgeTop = NSLayoutAttributeTop, + /** The bottom edge of the view. */ + ALEdgeBottom = NSLayoutAttributeBottom, + /** The leading edge of the view (left edge for left-to-right languages like English, right edge for right-to-left languages like Arabic). */ + ALEdgeLeading = NSLayoutAttributeLeading, + /** The trailing edge of the view (right edge for left-to-right languages like English, left edge for right-to-left languages like Arabic). */ + ALEdgeTrailing = NSLayoutAttributeTrailing +}; + +/** Constants that represent dimensions of a view. */ +typedef NS_ENUM(NSInteger, ALDimension) { + /** The width of the view. */ + ALDimensionWidth = NSLayoutAttributeWidth, + /** The height of the view. */ + ALDimensionHeight = NSLayoutAttributeHeight +}; + +/** Constants that represent axes of a view. */ +typedef NS_ENUM(NSInteger, ALAxis) { + /** A vertical line through the middle of the view's left and right edges. */ + ALAxisVertical = NSLayoutAttributeCenterX, + /** A horizontal line through the middle of the view's top and bottom edges. */ + ALAxisHorizontal = NSLayoutAttributeCenterY, + + /** A horizontal line at the baseline of the last line of text in the view. (For views that do not draw text, will be equivalent to ALEdgeBottom.) Same as ALAxisLastBaseline. */ + ALAxisBaseline = NSLayoutAttributeBaseline, + /** A horizontal line at the baseline of the last line of text in the view. (For views that do not draw text, will be equivalent to ALEdgeBottom.) */ + ALAxisLastBaseline = ALAxisBaseline, + #if __PureLayout_MinBaseSDK_iOS_8_0 + /** A horizontal line at the baseline of the first line of text in a view. (For views that do not draw text, will be equivalent to ALEdgeTop.) Available in iOS 8.0 and later. */ + ALAxisFirstBaseline = NSLayoutAttributeFirstBaseline + #endif /* __PureLayout_MinBaseSDK_iOS_8_0 */ +}; + +#if __PureLayout_MinBaseSDK_iOS_8_0 + +/** Constants that represent layout margins of a view. Available in iOS 8.0 and later. */ +typedef NS_ENUM(NSInteger, ALMargin) { + /** The left margin of the view, based on the view's layoutMargins left inset. */ + ALMarginLeft = NSLayoutAttributeLeftMargin, + /** The right margin of the view, based on the view's layoutMargins right inset. */ + ALMarginRight = NSLayoutAttributeRightMargin, + /** The top margin of the view, based on the view's layoutMargins top inset. */ + ALMarginTop = NSLayoutAttributeTopMargin, + /** The bottom margin of the view, based on the view's layoutMargins bottom inset. */ + ALMarginBottom = NSLayoutAttributeBottomMargin, + /** The leading margin of the view, based on the view's layoutMargins left/right (depending on language direction) inset. */ + ALMarginLeading = NSLayoutAttributeLeadingMargin, + /** The trailing margin of the view, based on the view's layoutMargins left/right (depending on language direction) inset. */ + ALMarginTrailing = NSLayoutAttributeTrailingMargin +}; + +/** Constants that represent axes of the layout margins of a view. Available in iOS 8.0 and later. */ +typedef NS_ENUM(NSInteger, ALMarginAxis) { + /** A vertical line through the middle of the view's left and right margins. */ + ALMarginAxisVertical = NSLayoutAttributeCenterXWithinMargins, + /** A horizontal line through the middle of the view's top and bottom margins. */ + ALMarginAxisHorizontal = NSLayoutAttributeCenterYWithinMargins +}; + +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 */ + +/** An attribute of a view that can be used in auto layout constraints. These constants are identical to the more specific enum types: + ALEdge, ALAxis, ALDimension, ALMargin, ALMarginAxis. It is safe to cast a more specific enum type to the ALAttribute type. */ +typedef NS_ENUM(NSInteger, ALAttribute) { + /** The left edge of the view. */ + ALAttributeLeft = ALEdgeLeft, + /** The right edge of the view. */ + ALAttributeRight = ALEdgeRight, + /** The top edge of the view. */ + ALAttributeTop = ALEdgeTop, + /** The bottom edge of the view. */ + ALAttributeBottom = ALEdgeBottom, + /** The leading edge of the view (left edge for left-to-right languages like English, right edge for right-to-left languages like Arabic). */ + ALAttributeLeading = ALEdgeLeading, + /** The trailing edge of the view (right edge for left-to-right languages like English, left edge for right-to-left languages like Arabic). */ + ALAttributeTrailing = ALEdgeTrailing, + /** The width of the view. */ + ALAttributeWidth = ALDimensionWidth, + /** The height of the view. */ + ALAttributeHeight = ALDimensionHeight, + /** A vertical line through the middle of the view's left and right edges. */ + ALAttributeVertical = ALAxisVertical, + /** A horizontal line through the middle of the view's top and bottom edges. */ + ALAttributeHorizontal = ALAxisHorizontal, + /** A horizontal line at the baseline of the last line of text in the view. (For views that do not draw text, will be equivalent to ALEdgeBottom.) Same as ALAxisLastBaseline. */ + ALAttributeBaseline = ALAxisBaseline, + /** A horizontal line at the baseline of the last line of text in the view. (For views that do not draw text, will be equivalent to ALEdgeBottom.) */ + ALAttributeLastBaseline = ALAxisLastBaseline, +#if __PureLayout_MinBaseSDK_iOS_8_0 + /** A horizontal line at the baseline of the first line of text in a view. (For views that do not draw text, will be equivalent to ALEdgeTop.) Available in iOS 8.0 and later. */ + ALAttributeFirstBaseline = ALAxisFirstBaseline, + /** The left margin of the view, based on the view's layoutMargins left inset. */ + ALAttributeMarginLeft = ALMarginLeft, + /** The right margin of the view, based on the view's layoutMargins right inset. */ + ALAttributeMarginRight = ALMarginRight, + /** The top margin of the view, based on the view's layoutMargins top inset. */ + ALAttributeMarginTop = ALMarginTop, + /** The bottom margin of the view, based on the view's layoutMargins bottom inset. */ + ALAttributeMarginBottom = ALMarginBottom, + /** The leading margin of the view, based on the view's layoutMargins left/right (depending on language direction) inset. */ + ALAttributeMarginLeading = ALMarginLeading, + /** The trailing margin of the view, based on the view's layoutMargins left/right (depending on language direction) inset. */ + ALAttributeMarginTrailing = ALMarginTrailing, + /** A vertical line through the middle of the view's left and right margins. */ + ALAttributeMarginAxisVertical = ALMarginAxisVertical, + /** A horizontal line through the middle of the view's top and bottom margins. */ + ALAttributeMarginAxisHorizontal = ALMarginAxisHorizontal +#endif /* __PureLayout_MinBaseSDK_iOS_8_0 */ +}; + +/** A block containing method calls to the PureLayout API. Takes no arguments and has no return value. */ +typedef void(^ALConstraintsBlock)(void); + +#endif /* PureLayoutDefines_h */ diff --git a/Example/Pods/PureLayout/README.md b/Example/Pods/PureLayout/README.md new file mode 100644 index 0000000..5eb3f7b --- /dev/null +++ b/Example/Pods/PureLayout/README.md @@ -0,0 +1,148 @@ +# [![PureLayout](https://github.com/smileyborg/PureLayout/blob/master/Images/PureLayout.png?raw=true)](#) +[![Build Status](http://img.shields.io/travis/smileyborg/PureLayout.svg?style=flat)](https://travis-ci.org/smileyborg/PureLayout) [![Test Coverage](http://img.shields.io/coveralls/smileyborg/PureLayout.svg?style=flat)](https://coveralls.io/r/smileyborg/PureLayout) [![Version](http://img.shields.io/cocoapods/v/PureLayout.svg?style=flat)](http://cocoapods.org/?q=PureLayout) [![Platform](http://img.shields.io/cocoapods/p/PureLayout.svg?style=flat)](http://cocoapods.org/?q=PureLayout) [![License](http://img.shields.io/cocoapods/l/PureLayout.svg?style=flat)](LICENSE) + +The ultimate API for iOS & OS X Auto Layout — impressively simple, immensely powerful. PureLayout extends `UIView`/`NSView`, `NSArray`, and `NSLayoutConstraint` with a comprehensive Auto Layout API that is modeled after Apple's own frameworks. PureLayout is an Objective-C library that also works (and looks!) great with Swift using a bridging header. + +Writing Auto Layout code from scratch isn't easy. PureLayout provides a fully capable and developer-friendly interface for Auto Layout. It is designed for clarity and simplicity, and takes inspiration from the AutoLayout UI options available in Interface Builder while delivering far more flexibility. The API is also highly efficient, as it adds only a thin layer of third party code and is engineered for maximum performance. + +## API Cheat Sheet +This is just a handy overview of the core API methods. Explore the [header files](PureLayout/PureLayout) for the full API, and find the complete documentation above the implementation of each method in the corresponding .m file. A couple of notes: + +* All of the public API methods are namespaced with the prefix `auto...`, which also makes it easy for Xcode to autocomplete as you type. +* Methods that create constraints also automatically install (activate) the constraint(s), then return the new constraint(s) for you to optionally store for later adjustment or removal. +* Many methods below also have a variant which includes a `relation:` parameter to make the constraint an inequality. + +### Attributes + +PureLayout defines view attributes that are used to create auto layout constraints. Here is an [illustration of the most common attributes](Images/PureLayout-CommonAttributes.png). + +There are 5 specific attribute types, which are used throughout most of the API: + +* `ALEdge` +* `ALDimension` +* `ALAxis` +* `ALMargin` *available in iOS 8.0 and higher only* +* `ALMarginAxis` *available in iOS 8.0 and higher only* + +Additionally, there is one generic attribute type, `ALAttribute`, which is effectively a union of all the specific types. You can think of this as the "supertype" of all of the specific attribute types, which means that it is always safe to cast a specific type to the generic `ALAttribute` type. (Note that the reverse is not true -- casting a generic ALAttribute to a specific attribute type is unsafe!) + +### [`UIView`/`NSView`](PureLayout/PureLayout/ALView%2BPureLayout.h) + + + autoCreateConstraintsWithoutInstalling: + + autoSetPriority:forConstraints: + + autoSetIdentifier:forConstraints: // iOS 7.0+, OS X 10.9+ only + - autoSetContent(CompressionResistance|Hugging)PriorityForAxis: + - autoCenterInSuperview: + - autoAlignAxisToSuperviewAxis: + - autoCenterInSuperviewMargins: // iOS 8.0+ only + - autoAlignAxisToSuperviewMarginAxis: // iOS 8.0+ only + - autoPinEdgeToSuperviewEdge:(withInset:) + - autoPinEdgesToSuperviewEdgesWithInsets:(excludingEdge:) + - autoPinEdgeToSuperviewMargin: // iOS 8.0+ only + - autoPinEdgesToSuperviewMargins(ExcludingEdge:) // iOS 8.0+ only + - autoPinEdge:toEdge:ofView:(withOffset:) + - autoAlignAxis:toSameAxisOfView:(withOffset:) + - autoMatchDimension:toDimension:ofView:(withOffset:|withMultiplier:) + - autoSetDimension(s)ToSize: + - autoConstrainAttribute:toAttribute:ofView:(withOffset:|withMultiplier:) + - autoPinTo(Top|Bottom)LayoutGuideOfViewController:withInset: // iOS only + +### [`NSArray`](PureLayout/PureLayout/NSArray%2BPureLayout.h) + + // Arrays of Constraints + - autoInstallConstraints + - autoRemoveConstraints + - autoIdentifyConstraints: // iOS 7.0+, OS X 10.9+ only + + // Arrays of Views + - autoAlignViewsToEdge: + - autoAlignViewsToAxis: + - autoMatchViewsDimension: + - autoSetViewsDimension:toSize: + - autoSetViewsDimensionsToSize: + - autoDistributeViewsAlongAxis:alignedTo:withFixedSpacing:(insetSpacing:)(matchedSizes:) + - autoDistributeViewsAlongAxis:alignedTo:withFixedSize:(insetSpacing:) + +### [`NSLayoutConstraint`](PureLayout/PureLayout/NSLayoutConstraint%2BPureLayout.h) + + - autoInstall + - autoRemove + - autoIdentify: // iOS 7.0+, OS X 10.9+ only + +## Setup +*Note: PureLayout requires a minimum deployment target of iOS 6.0 or OS X 10.7* + +### Using [CocoaPods](http://cocoapods.org) +1. Add the pod `PureLayout` to your [Podfile](http://guides.cocoapods.org/using/the-podfile.html). + + pod 'PureLayout' + +2. Run `pod install` from Terminal, then open your app's `.xcworkspace` file to launch Xcode. +3. Import the `PureLayout.h` header. Typically, this should be written as `#import ` + +That's it - now go write some beautiful Auto Layout code! + +### Using [Carthage](https://github.com/Carthage/Carthage) +1. Add the `smileyborg/PureLayout` project to your [Cartfile](https://github.com/Carthage/Carthage/blob/master/Documentation/Artifacts.md#cartfile). + + github "smileyborg/PureLayout" + +2. Run `carthage update`, then follow the [additional steps required](https://github.com/Carthage/Carthage#adding-frameworks-to-an-application) to add the iOS and/or Mac frameworks into your project. +3. Import the PureLayout framework/module (with the appropriate name for the platform you're using it on). + * Using Modules: `@import PureLayout_iOS` or `@import PureLayout_Mac` + * Without Modules: `#import ` or `#import ` + +That's it - now go write some beautiful Auto Layout code! + +### Manually from GitHub +1. Download the source files in the [PureLayout subdirectory](PureLayout/PureLayout). +2. Add the source files to your Xcode project. +3. Import the `PureLayout.h` header. + +That's it - now go write some beautiful Auto Layout code! + +### App Extensions +To use PureLayout in an App Extension, you need to do a bit of extra configuration to prevent usage of unavailable APIs. [Click here](https://github.com/smileyborg/PureLayout/wiki/App-Extensions) for more info. + +### Releases +Releases are tagged in the git commit history using [semantic versioning](http://semver.org). Check out the [releases and release notes](https://github.com/smileyborg/PureLayout/releases) for each version. + +## Usage +### Example Project +Open the project included in the repository (requires Xcode 6 or higher). It contains [iOS](PureLayout/Example-iOS) (`Example-iOS` scheme) and [OS X](PureLayout/Example-Mac) (`Example-Mac` scheme) demos of the library being used in various scenarios. + +On iOS, you can use different device simulators and rotate the device to see the constraints in action (as well as toggle the taller in-call status bar in the iOS Simulator). + +On OS X, while running the app, press any key to cycle through the demos. You can resize the window to see the constraints in action. + +### Tips and Tricks +Check out some [Tips and Tricks](https://github.com/smileyborg/PureLayout/wiki/Tips-and-Tricks) to keep in mind when using the API. + +## PureLayout vs. the rest +An overview of the Auto Layout options available, ordered from the lowest- to highest-level of abstraction. + +* Apple [NSLayoutConstraint SDK API](https://developer.apple.com/library/ios/documentation/AppKit/Reference/NSLayoutConstraint_Class/index.html#//apple_ref/occ/clm/NSLayoutConstraint/constraintWithItem:attribute:relatedBy:toItem:attribute:multiplier:constant:) + * Pros: Raw power + * Cons: Extremely verbose, tedious to write, difficult to read +* Apple [Visual Format Language](https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/VisualFormatLanguage/VisualFormatLanguage.html) + * Pros: Concise, convenient + * Cons: Doesn't support some use cases, incomplete compile-time checks, must learn syntax, hard to debug +* Apple Interface Builder + * Pros: Visual, simple + * Cons: Difficult for complex layouts, cannot dynamically set constraints at runtime, encourages hardcoded magic numbers, not always WYSIWYG +* **PureLayout** + * Pros: Simple, efficient, minimal third party code, consistent with Cocoa API style, compatible with Objective-C and Swift codebases + * Cons: Not the most concise expression of layout code +* High-level Auto Layout Libraries/DSLs ([Cartography](https://github.com/robb/Cartography), [SnapKit](https://github.com/SnapKit/SnapKit), [KeepLayout](https://github.com/iMartinKiss/KeepLayout)) + * Pros: Very clean, concise, and convenient + * Cons: Unique API style is foreign to Cocoa APIs, mixed compatibility with Objective-C & Swift, greater dependency on third party code + +PureLayout takes a balanced approach to Auto Layout that makes it well suited for any project. + +## Problems, Suggestions, Pull Requests? +Please open a [new Issue here](https://github.com/smileyborg/PureLayout/issues/new) if you run into an issue, have a feature request, or want to share a comment. Note that general Auto Layout questions should be asked on [Stack Overflow](http://stackoverflow.com). + +If you're considering taking on significant changes or additions to the project, please communicate in advance by opening a new Issue. This allows everyone to get onboard with upcoming changes, ensures that changes align with the project's design philosophy, and avoids duplicated work. + +## Meta +Designed & maintained by Tyler Fox ([@smileyborg](https://twitter.com/smileyborg)). Distributed with the MIT license. diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Example-TabBarPicker/Info.plist b/Example/Pods/Target Support Files/Pods-TabBarPicker_Example-TabBarPicker/Info.plist new file mode 100644 index 0000000..4ba5fa2 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Example-TabBarPicker/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + org.cocoapods.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 0.1.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Example-TabBarPicker/Pods-TabBarPicker_Example-TabBarPicker-Private.xcconfig b/Example/Pods/Target Support Files/Pods-TabBarPicker_Example-TabBarPicker/Pods-TabBarPicker_Example-TabBarPicker-Private.xcconfig new file mode 100644 index 0000000..2c12a9a --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Example-TabBarPicker/Pods-TabBarPicker_Example-TabBarPicker-Private.xcconfig @@ -0,0 +1,9 @@ +#include "Pods-TabBarPicker_Example-TabBarPicker.xcconfig" +CONFIGURATION_BUILD_DIR = $PODS_FRAMEWORK_BUILD_PATH +FRAMEWORK_SEARCH_PATHS = "$PODS_FRAMEWORK_BUILD_PATH" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/TabBarPicker" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/FBSnapshotTestCase" "${PODS_ROOT}/Headers/Public/PureLayout" "${PODS_ROOT}/Headers/Public/TabBarPicker" "${PODS_ROOT}/Headers/Public/pop" +OTHER_LDFLAGS = -ObjC +PODS_FRAMEWORK_BUILD_PATH = $(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Pods-TabBarPicker_Example +PODS_ROOT = ${SRCROOT} +SKIP_INSTALL = YES \ No newline at end of file diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Example-TabBarPicker/Pods-TabBarPicker_Example-TabBarPicker-dummy.m b/Example/Pods/Target Support Files/Pods-TabBarPicker_Example-TabBarPicker/Pods-TabBarPicker_Example-TabBarPicker-dummy.m new file mode 100644 index 0000000..a3d940c --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Example-TabBarPicker/Pods-TabBarPicker_Example-TabBarPicker-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_TabBarPicker_Example_TabBarPicker : NSObject +@end +@implementation PodsDummy_Pods_TabBarPicker_Example_TabBarPicker +@end diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Example-TabBarPicker/Pods-TabBarPicker_Example-TabBarPicker-prefix.pch b/Example/Pods/Target Support Files/Pods-TabBarPicker_Example-TabBarPicker/Pods-TabBarPicker_Example-TabBarPicker-prefix.pch new file mode 100644 index 0000000..0f9661b --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Example-TabBarPicker/Pods-TabBarPicker_Example-TabBarPicker-prefix.pch @@ -0,0 +1,5 @@ +#ifdef __OBJC__ +#import +#endif + +#import "Pods-TabBarPicker_Example-environment.h" diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Example-TabBarPicker/Pods-TabBarPicker_Example-TabBarPicker-umbrella.h b/Example/Pods/Target Support Files/Pods-TabBarPicker_Example-TabBarPicker/Pods-TabBarPicker_Example-TabBarPicker-umbrella.h new file mode 100644 index 0000000..a339c65 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Example-TabBarPicker/Pods-TabBarPicker_Example-TabBarPicker-umbrella.h @@ -0,0 +1,9 @@ +#import + +#import "TabBarItem.h" +#import "TabBarPicker.h" +#import "TabBarSubItem.h" + +FOUNDATION_EXPORT double TabBarPickerVersionNumber; +FOUNDATION_EXPORT const unsigned char TabBarPickerVersionString[]; + diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Example-TabBarPicker/Pods-TabBarPicker_Example-TabBarPicker.modulemap b/Example/Pods/Target Support Files/Pods-TabBarPicker_Example-TabBarPicker/Pods-TabBarPicker_Example-TabBarPicker.modulemap new file mode 100644 index 0000000..5836356 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Example-TabBarPicker/Pods-TabBarPicker_Example-TabBarPicker.modulemap @@ -0,0 +1,6 @@ +framework module TabBarPicker { + umbrella header "Pods-TabBarPicker_Example-TabBarPicker-umbrella.h" + + export * + module * { export * } +} diff --git a/Pod/Classes/ReplaceMe.m b/Example/Pods/Target Support Files/Pods-TabBarPicker_Example-TabBarPicker/Pods-TabBarPicker_Example-TabBarPicker.xcconfig similarity index 100% rename from Pod/Classes/ReplaceMe.m rename to Example/Pods/Target Support Files/Pods-TabBarPicker_Example-TabBarPicker/Pods-TabBarPicker_Example-TabBarPicker.xcconfig diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Example/Info.plist b/Example/Pods/Target Support Files/Pods-TabBarPicker_Example/Info.plist new file mode 100644 index 0000000..6974542 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Example/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + org.cocoapods.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Example/Pods-TabBarPicker_Example-acknowledgements.markdown b/Example/Pods/Target Support Files/Pods-TabBarPicker_Example/Pods-TabBarPicker_Example-acknowledgements.markdown new file mode 100644 index 0000000..d962d43 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Example/Pods-TabBarPicker_Example-acknowledgements.markdown @@ -0,0 +1,26 @@ +# Acknowledgements +This application makes use of the following third party libraries: + +## TabBarPicker + +Copyright (c) 2015 Giuseppe Nucifora + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +Generated by CocoaPods - http://cocoapods.org diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Example/Pods-TabBarPicker_Example-acknowledgements.plist b/Example/Pods/Target Support Files/Pods-TabBarPicker_Example/Pods-TabBarPicker_Example-acknowledgements.plist new file mode 100644 index 0000000..d45ca39 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Example/Pods-TabBarPicker_Example-acknowledgements.plist @@ -0,0 +1,56 @@ + + + + + PreferenceSpecifiers + + + FooterText + This application makes use of the following third party libraries: + Title + Acknowledgements + Type + PSGroupSpecifier + + + FooterText + Copyright (c) 2015 Giuseppe Nucifora <me@giuseppenucifora.com> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + Title + TabBarPicker + Type + PSGroupSpecifier + + + FooterText + Generated by CocoaPods - http://cocoapods.org + Title + + Type + PSGroupSpecifier + + + StringsTable + Acknowledgements + Title + Acknowledgements + + diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Example/Pods-TabBarPicker_Example-dummy.m b/Example/Pods/Target Support Files/Pods-TabBarPicker_Example/Pods-TabBarPicker_Example-dummy.m new file mode 100644 index 0000000..27158a4 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Example/Pods-TabBarPicker_Example-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_TabBarPicker_Example : NSObject +@end +@implementation PodsDummy_Pods_TabBarPicker_Example +@end diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Example/Pods-TabBarPicker_Example-environment.h b/Example/Pods/Target Support Files/Pods-TabBarPicker_Example/Pods-TabBarPicker_Example-environment.h new file mode 100644 index 0000000..0fe2be2 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Example/Pods-TabBarPicker_Example-environment.h @@ -0,0 +1,14 @@ + +// To check if a library is compiled with CocoaPods you +// can use the `COCOAPODS` macro definition which is +// defined in the xcconfigs so it is available in +// headers also when they are imported in the client +// project. + + +// TabBarPicker +#define COCOAPODS_POD_AVAILABLE_TabBarPicker +#define COCOAPODS_VERSION_MAJOR_TabBarPicker 0 +#define COCOAPODS_VERSION_MINOR_TabBarPicker 1 +#define COCOAPODS_VERSION_PATCH_TabBarPicker 0 + diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Example/Pods-TabBarPicker_Example-frameworks.sh b/Example/Pods/Target Support Files/Pods-TabBarPicker_Example/Pods-TabBarPicker_Example-frameworks.sh new file mode 100755 index 0000000..da9647b --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Example/Pods-TabBarPicker_Example-frameworks.sh @@ -0,0 +1,55 @@ +#!/bin/sh +set -e + +echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" +mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + +SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" + +install_framework() +{ + local source="${BUILT_PRODUCTS_DIR}/Pods-TabBarPicker_Example/$1" + local destination="${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + + if [ -L "${source}" ]; then + echo "Symlinked..." + source=$(readlink "${source}") + fi + + # use filter instead of exclude so missing patterns dont' throw errors + echo "rsync -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers/" --filter "- PrivateHeaders/" --filter "- Modules/" ${source} ${destination}" + rsync -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers/" --filter "- PrivateHeaders/" --filter "- Modules/" "${source}" "${destination}" + # Resign the code if required by the build settings to avoid unstable apps + if [ "${CODE_SIGNING_REQUIRED}" == "YES" ]; then + code_sign "${destination}/$1" + fi + + # Embed linked Swift runtime libraries + local basename + basename=$(echo $1 | sed -E s/\\..+// && exit ${PIPESTATUS[0]}) + local swift_runtime_libs + swift_runtime_libs=$(xcrun otool -LX "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/$1/${basename}" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) + for lib in $swift_runtime_libs; do + echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" + rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" + if [ "${CODE_SIGNING_REQUIRED}" == "YES" ]; then + code_sign "${destination}/${lib}" + fi + done +} + +# Signs a framework with the provided identity +code_sign() { + # Use the current code_sign_identitiy + echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" + echo "/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} --preserve-metadata=identifier,entitlements $1" + /usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} --preserve-metadata=identifier,entitlements "$1" +} + + +if [[ "$CONFIGURATION" == "Debug" ]]; then + install_framework 'TabBarPicker.framework' +fi +if [[ "$CONFIGURATION" == "Release" ]]; then + install_framework 'TabBarPicker.framework' +fi diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Example/Pods-TabBarPicker_Example-resources.sh b/Example/Pods/Target Support Files/Pods-TabBarPicker_Example/Pods-TabBarPicker_Example-resources.sh new file mode 100755 index 0000000..43f0852 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Example/Pods-TabBarPicker_Example-resources.sh @@ -0,0 +1,93 @@ +#!/bin/sh +set -e + +mkdir -p "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" + +RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt +> "$RESOURCES_TO_COPY" + +XCASSET_FILES=() + +realpath() { + DIRECTORY=$(cd "${1%/*}" && pwd) + FILENAME="${1##*/}" + echo "$DIRECTORY/$FILENAME" +} + +install_resource() +{ + case $1 in + *.storyboard) + echo "ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .storyboard`.storyboardc ${PODS_ROOT}/$1 --sdk ${SDKROOT}" + ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .storyboard`.storyboardc" "${PODS_ROOT}/$1" --sdk "${SDKROOT}" + ;; + *.xib) + echo "ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .xib`.nib ${PODS_ROOT}/$1 --sdk ${SDKROOT}" + ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .xib`.nib" "${PODS_ROOT}/$1" --sdk "${SDKROOT}" + ;; + *.framework) + echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + echo "rsync -av ${PODS_ROOT}/$1 ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + rsync -av "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + ;; + *.xcdatamodel) + echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1"`.mom\"" + xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodel`.mom" + ;; + *.xcdatamodeld) + echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd\"" + xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd" + ;; + *.xcmappingmodel) + echo "xcrun mapc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcmappingmodel`.cdm\"" + xcrun mapc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcmappingmodel`.cdm" + ;; + *.xcassets) + ABSOLUTE_XCASSET_FILE=$(realpath "${PODS_ROOT}/$1") + XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") + ;; + /*) + echo "$1" + echo "$1" >> "$RESOURCES_TO_COPY" + ;; + *) + echo "${PODS_ROOT}/$1" + echo "${PODS_ROOT}/$1" >> "$RESOURCES_TO_COPY" + ;; + esac +} + +rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +if [[ "${ACTION}" == "install" ]]; then + rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +fi +rm -f "$RESOURCES_TO_COPY" + +if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ] +then + case "${TARGETED_DEVICE_FAMILY}" in + 1,2) + TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" + ;; + 1) + TARGET_DEVICE_ARGS="--target-device iphone" + ;; + 2) + TARGET_DEVICE_ARGS="--target-device ipad" + ;; + *) + TARGET_DEVICE_ARGS="--target-device mac" + ;; + esac + + # Find all other xcassets (this unfortunately includes those of path pods and other targets). + OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) + while read line; do + if [[ $line != "`realpath $PODS_ROOT`*" ]]; then + XCASSET_FILES+=("$line") + fi + done <<<"$OTHER_XCASSETS" + + printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${IPHONEOS_DEPLOYMENT_TARGET}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +fi diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Example/Pods-TabBarPicker_Example-umbrella.h b/Example/Pods/Target Support Files/Pods-TabBarPicker_Example/Pods-TabBarPicker_Example-umbrella.h new file mode 100644 index 0000000..16a53c3 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Example/Pods-TabBarPicker_Example-umbrella.h @@ -0,0 +1,6 @@ +#import + + +FOUNDATION_EXPORT double Pods_TabBarPicker_ExampleVersionNumber; +FOUNDATION_EXPORT const unsigned char Pods_TabBarPicker_ExampleVersionString[]; + diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Example/Pods-TabBarPicker_Example.debug.xcconfig b/Example/Pods/Target Support Files/Pods-TabBarPicker_Example/Pods-TabBarPicker_Example.debug.xcconfig new file mode 100644 index 0000000..a08956e --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Example/Pods-TabBarPicker_Example.debug.xcconfig @@ -0,0 +1,8 @@ +FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_FRAMEWORK_BUILD_PATH" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' +OTHER_CFLAGS = $(inherited) -iquote "$PODS_FRAMEWORK_BUILD_PATH/TabBarPicker.framework/Headers" +OTHER_LDFLAGS = $(inherited) -ObjC -framework "TabBarPicker" +OTHER_LIBTOOLFLAGS = $(OTHER_LDFLAGS) +PODS_FRAMEWORK_BUILD_PATH = $(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Pods-TabBarPicker_Example +PODS_ROOT = ${SRCROOT}/Pods \ No newline at end of file diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Example/Pods-TabBarPicker_Example.modulemap b/Example/Pods/Target Support Files/Pods-TabBarPicker_Example/Pods-TabBarPicker_Example.modulemap new file mode 100644 index 0000000..7e57eb4 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Example/Pods-TabBarPicker_Example.modulemap @@ -0,0 +1,6 @@ +framework module Pods_TabBarPicker_Example { + umbrella header "Pods-TabBarPicker_Example-umbrella.h" + + export * + module * { export * } +} diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Example/Pods-TabBarPicker_Example.release.xcconfig b/Example/Pods/Target Support Files/Pods-TabBarPicker_Example/Pods-TabBarPicker_Example.release.xcconfig new file mode 100644 index 0000000..a08956e --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Example/Pods-TabBarPicker_Example.release.xcconfig @@ -0,0 +1,8 @@ +FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_FRAMEWORK_BUILD_PATH" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' +OTHER_CFLAGS = $(inherited) -iquote "$PODS_FRAMEWORK_BUILD_PATH/TabBarPicker.framework/Headers" +OTHER_LDFLAGS = $(inherited) -ObjC -framework "TabBarPicker" +OTHER_LIBTOOLFLAGS = $(OTHER_LDFLAGS) +PODS_FRAMEWORK_BUILD_PATH = $(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Pods-TabBarPicker_Example +PODS_ROOT = ${SRCROOT}/Pods \ No newline at end of file diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-FBSnapshotTestCase/Info.plist b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-FBSnapshotTestCase/Info.plist new file mode 100644 index 0000000..55d4a94 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-FBSnapshotTestCase/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + org.cocoapods.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 2.0.2 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-FBSnapshotTestCase/Pods-TabBarPicker_Tests-FBSnapshotTestCase-Private.xcconfig b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-FBSnapshotTestCase/Pods-TabBarPicker_Tests-FBSnapshotTestCase-Private.xcconfig new file mode 100644 index 0000000..afddba9 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-FBSnapshotTestCase/Pods-TabBarPicker_Tests-FBSnapshotTestCase-Private.xcconfig @@ -0,0 +1,10 @@ +#include "Pods-TabBarPicker_Tests-FBSnapshotTestCase.xcconfig" +CONFIGURATION_BUILD_DIR = $PODS_FRAMEWORK_BUILD_PATH +FRAMEWORK_SEARCH_PATHS = "$PODS_FRAMEWORK_BUILD_PATH" ${PODS_TABBARPICKER_TESTS_FBSNAPSHOTTESTCASE_FRAMEWORK_SEARCH_PATHS} +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/FBSnapshotTestCase" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/FBSnapshotTestCase" "${PODS_ROOT}/Headers/Public/PureLayout" "${PODS_ROOT}/Headers/Public/TabBarPicker" "${PODS_ROOT}/Headers/Public/pop" +OTHER_LDFLAGS = ${PODS_TABBARPICKER_TESTS_FBSNAPSHOTTESTCASE_OTHER_LDFLAGS} -ObjC +OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" +PODS_FRAMEWORK_BUILD_PATH = $(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Pods-TabBarPicker_Tests +PODS_ROOT = ${SRCROOT} +SKIP_INSTALL = YES \ No newline at end of file diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-FBSnapshotTestCase/Pods-TabBarPicker_Tests-FBSnapshotTestCase-dummy.m b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-FBSnapshotTestCase/Pods-TabBarPicker_Tests-FBSnapshotTestCase-dummy.m new file mode 100644 index 0000000..60034d9 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-FBSnapshotTestCase/Pods-TabBarPicker_Tests-FBSnapshotTestCase-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_TabBarPicker_Tests_FBSnapshotTestCase : NSObject +@end +@implementation PodsDummy_Pods_TabBarPicker_Tests_FBSnapshotTestCase +@end diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-FBSnapshotTestCase/Pods-TabBarPicker_Tests-FBSnapshotTestCase-prefix.pch b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-FBSnapshotTestCase/Pods-TabBarPicker_Tests-FBSnapshotTestCase-prefix.pch new file mode 100644 index 0000000..e6ffe76 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-FBSnapshotTestCase/Pods-TabBarPicker_Tests-FBSnapshotTestCase-prefix.pch @@ -0,0 +1,5 @@ +#ifdef __OBJC__ +#import +#endif + +#import "Pods-TabBarPicker_Tests-environment.h" diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-FBSnapshotTestCase/Pods-TabBarPicker_Tests-FBSnapshotTestCase-umbrella.h b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-FBSnapshotTestCase/Pods-TabBarPicker_Tests-FBSnapshotTestCase-umbrella.h new file mode 100644 index 0000000..a41867f --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-FBSnapshotTestCase/Pods-TabBarPicker_Tests-FBSnapshotTestCase-umbrella.h @@ -0,0 +1,13 @@ +#import + +#import "FBSnapshotTestCase.h" +#import "FBSnapshotTestCasePlatform.h" +#import "FBSnapshotTestCase.h" +#import "FBSnapshotTestCasePlatform.h" +#import "FBSnapshotTestController.h" +#import "UIImage+Compare.h" +#import "UIImage+Diff.h" + +FOUNDATION_EXPORT double FBSnapshotTestCaseVersionNumber; +FOUNDATION_EXPORT const unsigned char FBSnapshotTestCaseVersionString[]; + diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-FBSnapshotTestCase/Pods-TabBarPicker_Tests-FBSnapshotTestCase.modulemap b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-FBSnapshotTestCase/Pods-TabBarPicker_Tests-FBSnapshotTestCase.modulemap new file mode 100644 index 0000000..2e9bc24 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-FBSnapshotTestCase/Pods-TabBarPicker_Tests-FBSnapshotTestCase.modulemap @@ -0,0 +1,10 @@ +framework module FBSnapshotTestCase { + umbrella header "Pods-TabBarPicker_Tests-FBSnapshotTestCase-umbrella.h" + + export * + module * { export * } + + private header "FBSnapshotTestController.h" + private header "UIImage+Compare.h" + private header "UIImage+Diff.h" +} diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-FBSnapshotTestCase/Pods-TabBarPicker_Tests-FBSnapshotTestCase.xcconfig b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-FBSnapshotTestCase/Pods-TabBarPicker_Tests-FBSnapshotTestCase.xcconfig new file mode 100644 index 0000000..d5c5a02 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-FBSnapshotTestCase/Pods-TabBarPicker_Tests-FBSnapshotTestCase.xcconfig @@ -0,0 +1,2 @@ +PODS_TABBARPICKER_TESTS_FBSNAPSHOTTESTCASE_FRAMEWORK_SEARCH_PATHS = $(inherited) "$(SDKROOT)/Developer/Library/Frameworks" "$(PLATFORM_DIR)/Developer/Library/Frameworks" +PODS_TABBARPICKER_TESTS_FBSNAPSHOTTESTCASE_OTHER_LDFLAGS = -framework "XCTest" \ No newline at end of file diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-PureLayout/Info.plist b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-PureLayout/Info.plist new file mode 100644 index 0000000..88f5e5f --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-PureLayout/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + org.cocoapods.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 2.0.6 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-PureLayout/Pods-TabBarPicker_Tests-PureLayout-Private.xcconfig b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-PureLayout/Pods-TabBarPicker_Tests-PureLayout-Private.xcconfig new file mode 100644 index 0000000..651a10b --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-PureLayout/Pods-TabBarPicker_Tests-PureLayout-Private.xcconfig @@ -0,0 +1,9 @@ +#include "Pods-TabBarPicker_Tests-PureLayout.xcconfig" +CONFIGURATION_BUILD_DIR = $PODS_FRAMEWORK_BUILD_PATH +FRAMEWORK_SEARCH_PATHS = "$PODS_FRAMEWORK_BUILD_PATH" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/PureLayout" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/FBSnapshotTestCase" "${PODS_ROOT}/Headers/Public/PureLayout" "${PODS_ROOT}/Headers/Public/TabBarPicker" "${PODS_ROOT}/Headers/Public/pop" +OTHER_LDFLAGS = -ObjC +PODS_FRAMEWORK_BUILD_PATH = $(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Pods-TabBarPicker_Tests +PODS_ROOT = ${SRCROOT} +SKIP_INSTALL = YES \ No newline at end of file diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-PureLayout/Pods-TabBarPicker_Tests-PureLayout-dummy.m b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-PureLayout/Pods-TabBarPicker_Tests-PureLayout-dummy.m new file mode 100644 index 0000000..a17ff54 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-PureLayout/Pods-TabBarPicker_Tests-PureLayout-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_TabBarPicker_Tests_PureLayout : NSObject +@end +@implementation PodsDummy_Pods_TabBarPicker_Tests_PureLayout +@end diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-PureLayout/Pods-TabBarPicker_Tests-PureLayout-prefix.pch b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-PureLayout/Pods-TabBarPicker_Tests-PureLayout-prefix.pch new file mode 100644 index 0000000..e6ffe76 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-PureLayout/Pods-TabBarPicker_Tests-PureLayout-prefix.pch @@ -0,0 +1,5 @@ +#ifdef __OBJC__ +#import +#endif + +#import "Pods-TabBarPicker_Tests-environment.h" diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-PureLayout/Pods-TabBarPicker_Tests-PureLayout-umbrella.h b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-PureLayout/Pods-TabBarPicker_Tests-PureLayout-umbrella.h new file mode 100644 index 0000000..b50c609 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-PureLayout/Pods-TabBarPicker_Tests-PureLayout-umbrella.h @@ -0,0 +1,12 @@ +#import + +#import "ALView+PureLayout.h" +#import "NSArray+PureLayout.h" +#import "NSLayoutConstraint+PureLayout.h" +#import "PureLayout+Internal.h" +#import "PureLayout.h" +#import "PureLayoutDefines.h" + +FOUNDATION_EXPORT double PureLayoutVersionNumber; +FOUNDATION_EXPORT const unsigned char PureLayoutVersionString[]; + diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-PureLayout/Pods-TabBarPicker_Tests-PureLayout.modulemap b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-PureLayout/Pods-TabBarPicker_Tests-PureLayout.modulemap new file mode 100644 index 0000000..0fa6d4f --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-PureLayout/Pods-TabBarPicker_Tests-PureLayout.modulemap @@ -0,0 +1,6 @@ +framework module PureLayout { + umbrella header "Pods-TabBarPicker_Tests-PureLayout-umbrella.h" + + export * + module * { export * } +} diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-PureLayout/Pods-TabBarPicker_Tests-PureLayout.xcconfig b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-PureLayout/Pods-TabBarPicker_Tests-PureLayout.xcconfig new file mode 100644 index 0000000..e69de29 diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-TabBarPicker/Info.plist b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-TabBarPicker/Info.plist new file mode 100644 index 0000000..4ba5fa2 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-TabBarPicker/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + org.cocoapods.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 0.1.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-TabBarPicker/Pods-TabBarPicker_Tests-TabBarPicker-Private.xcconfig b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-TabBarPicker/Pods-TabBarPicker_Tests-TabBarPicker-Private.xcconfig new file mode 100644 index 0000000..394b498 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-TabBarPicker/Pods-TabBarPicker_Tests-TabBarPicker-Private.xcconfig @@ -0,0 +1,9 @@ +#include "Pods-TabBarPicker_Tests-TabBarPicker.xcconfig" +CONFIGURATION_BUILD_DIR = $PODS_FRAMEWORK_BUILD_PATH +FRAMEWORK_SEARCH_PATHS = "$PODS_FRAMEWORK_BUILD_PATH" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/TabBarPicker" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/FBSnapshotTestCase" "${PODS_ROOT}/Headers/Public/PureLayout" "${PODS_ROOT}/Headers/Public/TabBarPicker" "${PODS_ROOT}/Headers/Public/pop" +OTHER_LDFLAGS = -ObjC +PODS_FRAMEWORK_BUILD_PATH = $(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Pods-TabBarPicker_Tests +PODS_ROOT = ${SRCROOT} +SKIP_INSTALL = YES \ No newline at end of file diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-TabBarPicker/Pods-TabBarPicker_Tests-TabBarPicker-dummy.m b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-TabBarPicker/Pods-TabBarPicker_Tests-TabBarPicker-dummy.m new file mode 100644 index 0000000..629ec6f --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-TabBarPicker/Pods-TabBarPicker_Tests-TabBarPicker-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_TabBarPicker_Tests_TabBarPicker : NSObject +@end +@implementation PodsDummy_Pods_TabBarPicker_Tests_TabBarPicker +@end diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-TabBarPicker/Pods-TabBarPicker_Tests-TabBarPicker-prefix.pch b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-TabBarPicker/Pods-TabBarPicker_Tests-TabBarPicker-prefix.pch new file mode 100644 index 0000000..e6ffe76 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-TabBarPicker/Pods-TabBarPicker_Tests-TabBarPicker-prefix.pch @@ -0,0 +1,5 @@ +#ifdef __OBJC__ +#import +#endif + +#import "Pods-TabBarPicker_Tests-environment.h" diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-TabBarPicker/Pods-TabBarPicker_Tests-TabBarPicker-umbrella.h b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-TabBarPicker/Pods-TabBarPicker_Tests-TabBarPicker-umbrella.h new file mode 100644 index 0000000..a339c65 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-TabBarPicker/Pods-TabBarPicker_Tests-TabBarPicker-umbrella.h @@ -0,0 +1,9 @@ +#import + +#import "TabBarItem.h" +#import "TabBarPicker.h" +#import "TabBarSubItem.h" + +FOUNDATION_EXPORT double TabBarPickerVersionNumber; +FOUNDATION_EXPORT const unsigned char TabBarPickerVersionString[]; + diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-TabBarPicker/Pods-TabBarPicker_Tests-TabBarPicker.modulemap b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-TabBarPicker/Pods-TabBarPicker_Tests-TabBarPicker.modulemap new file mode 100644 index 0000000..1f8fead --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-TabBarPicker/Pods-TabBarPicker_Tests-TabBarPicker.modulemap @@ -0,0 +1,6 @@ +framework module TabBarPicker { + umbrella header "Pods-TabBarPicker_Tests-TabBarPicker-umbrella.h" + + export * + module * { export * } +} diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-TabBarPicker/Pods-TabBarPicker_Tests-TabBarPicker.xcconfig b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-TabBarPicker/Pods-TabBarPicker_Tests-TabBarPicker.xcconfig new file mode 100644 index 0000000..e69de29 diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-pop/Info.plist b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-pop/Info.plist new file mode 100644 index 0000000..f3506fc --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-pop/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + org.cocoapods.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0.7 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-pop/Pods-TabBarPicker_Tests-pop-Private.xcconfig b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-pop/Pods-TabBarPicker_Tests-pop-Private.xcconfig new file mode 100644 index 0000000..47a0892 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-pop/Pods-TabBarPicker_Tests-pop-Private.xcconfig @@ -0,0 +1,11 @@ +#include "Pods-TabBarPicker_Tests-pop.xcconfig" +CLANG_CXX_LANGUAGE_STANDARD = ${PODS_TABBARPICKER_TESTS_POP_CLANG_CXX_LANGUAGE_STANDARD} +CLANG_CXX_LIBRARY = ${PODS_TABBARPICKER_TESTS_POP_CLANG_CXX_LIBRARY} +CONFIGURATION_BUILD_DIR = $PODS_FRAMEWORK_BUILD_PATH +FRAMEWORK_SEARCH_PATHS = "$PODS_FRAMEWORK_BUILD_PATH" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Private/pop" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/FBSnapshotTestCase" "${PODS_ROOT}/Headers/Public/PureLayout" "${PODS_ROOT}/Headers/Public/TabBarPicker" "${PODS_ROOT}/Headers/Public/pop" +OTHER_LDFLAGS = ${PODS_TABBARPICKER_TESTS_POP_OTHER_LDFLAGS} -ObjC +PODS_FRAMEWORK_BUILD_PATH = $(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Pods-TabBarPicker_Tests +PODS_ROOT = ${SRCROOT} +SKIP_INSTALL = YES \ No newline at end of file diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-pop/Pods-TabBarPicker_Tests-pop-dummy.m b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-pop/Pods-TabBarPicker_Tests-pop-dummy.m new file mode 100644 index 0000000..dfd2df6 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-pop/Pods-TabBarPicker_Tests-pop-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_TabBarPicker_Tests_pop : NSObject +@end +@implementation PodsDummy_Pods_TabBarPicker_Tests_pop +@end diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-pop/Pods-TabBarPicker_Tests-pop-prefix.pch b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-pop/Pods-TabBarPicker_Tests-pop-prefix.pch new file mode 100644 index 0000000..e6ffe76 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-pop/Pods-TabBarPicker_Tests-pop-prefix.pch @@ -0,0 +1,5 @@ +#ifdef __OBJC__ +#import +#endif + +#import "Pods-TabBarPicker_Tests-environment.h" diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-pop/Pods-TabBarPicker_Tests-pop-umbrella.h b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-pop/Pods-TabBarPicker_Tests-pop-umbrella.h new file mode 100644 index 0000000..3f8318a --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-pop/Pods-TabBarPicker_Tests-pop-umbrella.h @@ -0,0 +1,21 @@ +#import + +#import "POP.h" +#import "POPAnimatableProperty.h" +#import "POPAnimation.h" +#import "POPAnimationEvent.h" +#import "POPAnimationExtras.h" +#import "POPAnimationTracer.h" +#import "POPAnimator.h" +#import "POPBasicAnimation.h" +#import "POPCustomAnimation.h" +#import "POPDecayAnimation.h" +#import "POPDefines.h" +#import "POPGeometry.h" +#import "POPLayerExtras.h" +#import "POPPropertyAnimation.h" +#import "POPSpringAnimation.h" + +FOUNDATION_EXPORT double popVersionNumber; +FOUNDATION_EXPORT const unsigned char popVersionString[]; + diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-pop/Pods-TabBarPicker_Tests-pop.modulemap b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-pop/Pods-TabBarPicker_Tests-pop.modulemap new file mode 100644 index 0000000..8c88701 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-pop/Pods-TabBarPicker_Tests-pop.modulemap @@ -0,0 +1,6 @@ +framework module pop { + umbrella header "Pods-TabBarPicker_Tests-pop-umbrella.h" + + export * + module * { export * } +} diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-pop/Pods-TabBarPicker_Tests-pop.xcconfig b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-pop/Pods-TabBarPicker_Tests-pop.xcconfig new file mode 100644 index 0000000..474a17b --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests-pop/Pods-TabBarPicker_Tests-pop.xcconfig @@ -0,0 +1,3 @@ +PODS_TABBARPICKER_TESTS_POP_CLANG_CXX_LANGUAGE_STANDARD = c++11 +PODS_TABBARPICKER_TESTS_POP_CLANG_CXX_LIBRARY = libc++ +PODS_TABBARPICKER_TESTS_POP_OTHER_LDFLAGS = -l"c++" \ No newline at end of file diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests/Info.plist b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests/Info.plist new file mode 100644 index 0000000..6974542 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + org.cocoapods.${PRODUCT_NAME:rfc1034identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests/Pods-TabBarPicker_Tests-acknowledgements.markdown b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests/Pods-TabBarPicker_Tests-acknowledgements.markdown new file mode 100644 index 0000000..9a97f50 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests/Pods-TabBarPicker_Tests-acknowledgements.markdown @@ -0,0 +1,106 @@ +# Acknowledgements +This application makes use of the following third party libraries: + +## FBSnapshotTestCase + +BSD License + +For the FBSnapshotTestCase software + +Copyright (c) 2013, Facebook, Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name Facebook nor the names of its contributors may be used to + endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +## PureLayout + +This code is distributed under the terms and conditions of the MIT license. + +Copyright (c) 2014-2015 Tyler Fox + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +## TabBarPicker + +Copyright (c) 2015 Giuseppe Nucifora + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +## pop + +BSD License + +For Pop software + +Copyright (c) 2014, Facebook, Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name Facebook nor the names of its contributors may be used to + endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Generated by CocoaPods - http://cocoapods.org diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests/Pods-TabBarPicker_Tests-acknowledgements.plist b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests/Pods-TabBarPicker_Tests-acknowledgements.plist new file mode 100644 index 0000000..1e0e7dc --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests/Pods-TabBarPicker_Tests-acknowledgements.plist @@ -0,0 +1,148 @@ + + + + + PreferenceSpecifiers + + + FooterText + This application makes use of the following third party libraries: + Title + Acknowledgements + Type + PSGroupSpecifier + + + FooterText + BSD License + +For the FBSnapshotTestCase software + +Copyright (c) 2013, Facebook, Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name Facebook nor the names of its contributors may be used to + endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Title + FBSnapshotTestCase + Type + PSGroupSpecifier + + + FooterText + This code is distributed under the terms and conditions of the MIT license. + +Copyright (c) 2014-2015 Tyler Fox + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Title + PureLayout + Type + PSGroupSpecifier + + + FooterText + Copyright (c) 2015 Giuseppe Nucifora <me@giuseppenucifora.com> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + Title + TabBarPicker + Type + PSGroupSpecifier + + + FooterText + BSD License + +For Pop software + +Copyright (c) 2014, Facebook, Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name Facebook nor the names of its contributors may be used to + endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Title + pop + Type + PSGroupSpecifier + + + FooterText + Generated by CocoaPods - http://cocoapods.org + Title + + Type + PSGroupSpecifier + + + StringsTable + Acknowledgements + Title + Acknowledgements + + diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests/Pods-TabBarPicker_Tests-dummy.m b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests/Pods-TabBarPicker_Tests-dummy.m new file mode 100644 index 0000000..22faaba --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests/Pods-TabBarPicker_Tests-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_TabBarPicker_Tests : NSObject +@end +@implementation PodsDummy_Pods_TabBarPicker_Tests +@end diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests/Pods-TabBarPicker_Tests-environment.h b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests/Pods-TabBarPicker_Tests-environment.h new file mode 100644 index 0000000..578a85c --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests/Pods-TabBarPicker_Tests-environment.h @@ -0,0 +1,44 @@ + +// To check if a library is compiled with CocoaPods you +// can use the `COCOAPODS` macro definition which is +// defined in the xcconfigs so it is available in +// headers also when they are imported in the client +// project. + + +// FBSnapshotTestCase +#define COCOAPODS_POD_AVAILABLE_FBSnapshotTestCase +#define COCOAPODS_VERSION_MAJOR_FBSnapshotTestCase 2 +#define COCOAPODS_VERSION_MINOR_FBSnapshotTestCase 0 +#define COCOAPODS_VERSION_PATCH_FBSnapshotTestCase 2 + +// FBSnapshotTestCase/Core +#define COCOAPODS_POD_AVAILABLE_FBSnapshotTestCase_Core +#define COCOAPODS_VERSION_MAJOR_FBSnapshotTestCase_Core 2 +#define COCOAPODS_VERSION_MINOR_FBSnapshotTestCase_Core 0 +#define COCOAPODS_VERSION_PATCH_FBSnapshotTestCase_Core 2 + +// FBSnapshotTestCase/SwiftSupport +#define COCOAPODS_POD_AVAILABLE_FBSnapshotTestCase_SwiftSupport +#define COCOAPODS_VERSION_MAJOR_FBSnapshotTestCase_SwiftSupport 2 +#define COCOAPODS_VERSION_MINOR_FBSnapshotTestCase_SwiftSupport 0 +#define COCOAPODS_VERSION_PATCH_FBSnapshotTestCase_SwiftSupport 2 + +// PureLayout +#define COCOAPODS_POD_AVAILABLE_PureLayout +#define COCOAPODS_VERSION_MAJOR_PureLayout 2 +#define COCOAPODS_VERSION_MINOR_PureLayout 0 +#define COCOAPODS_VERSION_PATCH_PureLayout 6 + +// TabBarPicker +#define COCOAPODS_POD_AVAILABLE_TabBarPicker +#define COCOAPODS_VERSION_MAJOR_TabBarPicker 0 +#define COCOAPODS_VERSION_MINOR_TabBarPicker 1 +#define COCOAPODS_VERSION_PATCH_TabBarPicker 0 + +// pop +#define COCOAPODS_POD_AVAILABLE_pop +#define COCOAPODS_VERSION_MAJOR_pop 1 +#define COCOAPODS_VERSION_MINOR_pop 0 +#define COCOAPODS_VERSION_PATCH_pop 7 + diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests/Pods-TabBarPicker_Tests-frameworks.sh b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests/Pods-TabBarPicker_Tests-frameworks.sh new file mode 100755 index 0000000..4b6de7e --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests/Pods-TabBarPicker_Tests-frameworks.sh @@ -0,0 +1,61 @@ +#!/bin/sh +set -e + +echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" +mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + +SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" + +install_framework() +{ + local source="${BUILT_PRODUCTS_DIR}/Pods-TabBarPicker_Tests/$1" + local destination="${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + + if [ -L "${source}" ]; then + echo "Symlinked..." + source=$(readlink "${source}") + fi + + # use filter instead of exclude so missing patterns dont' throw errors + echo "rsync -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers/" --filter "- PrivateHeaders/" --filter "- Modules/" ${source} ${destination}" + rsync -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers/" --filter "- PrivateHeaders/" --filter "- Modules/" "${source}" "${destination}" + # Resign the code if required by the build settings to avoid unstable apps + if [ "${CODE_SIGNING_REQUIRED}" == "YES" ]; then + code_sign "${destination}/$1" + fi + + # Embed linked Swift runtime libraries + local basename + basename=$(echo $1 | sed -E s/\\..+// && exit ${PIPESTATUS[0]}) + local swift_runtime_libs + swift_runtime_libs=$(xcrun otool -LX "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/$1/${basename}" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) + for lib in $swift_runtime_libs; do + echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" + rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" + if [ "${CODE_SIGNING_REQUIRED}" == "YES" ]; then + code_sign "${destination}/${lib}" + fi + done +} + +# Signs a framework with the provided identity +code_sign() { + # Use the current code_sign_identitiy + echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" + echo "/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} --preserve-metadata=identifier,entitlements $1" + /usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} --preserve-metadata=identifier,entitlements "$1" +} + + +if [[ "$CONFIGURATION" == "Debug" ]]; then + install_framework 'FBSnapshotTestCase.framework' + install_framework 'PureLayout.framework' + install_framework 'TabBarPicker.framework' + install_framework 'pop.framework' +fi +if [[ "$CONFIGURATION" == "Release" ]]; then + install_framework 'FBSnapshotTestCase.framework' + install_framework 'PureLayout.framework' + install_framework 'TabBarPicker.framework' + install_framework 'pop.framework' +fi diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests/Pods-TabBarPicker_Tests-resources.sh b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests/Pods-TabBarPicker_Tests-resources.sh new file mode 100755 index 0000000..43f0852 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests/Pods-TabBarPicker_Tests-resources.sh @@ -0,0 +1,93 @@ +#!/bin/sh +set -e + +mkdir -p "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" + +RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt +> "$RESOURCES_TO_COPY" + +XCASSET_FILES=() + +realpath() { + DIRECTORY=$(cd "${1%/*}" && pwd) + FILENAME="${1##*/}" + echo "$DIRECTORY/$FILENAME" +} + +install_resource() +{ + case $1 in + *.storyboard) + echo "ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .storyboard`.storyboardc ${PODS_ROOT}/$1 --sdk ${SDKROOT}" + ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .storyboard`.storyboardc" "${PODS_ROOT}/$1" --sdk "${SDKROOT}" + ;; + *.xib) + echo "ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .xib`.nib ${PODS_ROOT}/$1 --sdk ${SDKROOT}" + ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .xib`.nib" "${PODS_ROOT}/$1" --sdk "${SDKROOT}" + ;; + *.framework) + echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + echo "rsync -av ${PODS_ROOT}/$1 ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + rsync -av "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + ;; + *.xcdatamodel) + echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1"`.mom\"" + xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodel`.mom" + ;; + *.xcdatamodeld) + echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd\"" + xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd" + ;; + *.xcmappingmodel) + echo "xcrun mapc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcmappingmodel`.cdm\"" + xcrun mapc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcmappingmodel`.cdm" + ;; + *.xcassets) + ABSOLUTE_XCASSET_FILE=$(realpath "${PODS_ROOT}/$1") + XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") + ;; + /*) + echo "$1" + echo "$1" >> "$RESOURCES_TO_COPY" + ;; + *) + echo "${PODS_ROOT}/$1" + echo "${PODS_ROOT}/$1" >> "$RESOURCES_TO_COPY" + ;; + esac +} + +rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +if [[ "${ACTION}" == "install" ]]; then + rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +fi +rm -f "$RESOURCES_TO_COPY" + +if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ] +then + case "${TARGETED_DEVICE_FAMILY}" in + 1,2) + TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" + ;; + 1) + TARGET_DEVICE_ARGS="--target-device iphone" + ;; + 2) + TARGET_DEVICE_ARGS="--target-device ipad" + ;; + *) + TARGET_DEVICE_ARGS="--target-device mac" + ;; + esac + + # Find all other xcassets (this unfortunately includes those of path pods and other targets). + OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) + while read line; do + if [[ $line != "`realpath $PODS_ROOT`*" ]]; then + XCASSET_FILES+=("$line") + fi + done <<<"$OTHER_XCASSETS" + + printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${IPHONEOS_DEPLOYMENT_TARGET}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +fi diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests/Pods-TabBarPicker_Tests-umbrella.h b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests/Pods-TabBarPicker_Tests-umbrella.h new file mode 100644 index 0000000..8cb49a8 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests/Pods-TabBarPicker_Tests-umbrella.h @@ -0,0 +1,6 @@ +#import + + +FOUNDATION_EXPORT double Pods_TabBarPicker_TestsVersionNumber; +FOUNDATION_EXPORT const unsigned char Pods_TabBarPicker_TestsVersionString[]; + diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests/Pods-TabBarPicker_Tests.debug.xcconfig b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests/Pods-TabBarPicker_Tests.debug.xcconfig new file mode 100644 index 0000000..370c7c3 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests/Pods-TabBarPicker_Tests.debug.xcconfig @@ -0,0 +1,9 @@ +FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_FRAMEWORK_BUILD_PATH" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' +OTHER_CFLAGS = $(inherited) -iquote "$PODS_FRAMEWORK_BUILD_PATH/FBSnapshotTestCase.framework/Headers" -iquote "$PODS_FRAMEWORK_BUILD_PATH/PureLayout.framework/Headers" -iquote "$PODS_FRAMEWORK_BUILD_PATH/TabBarPicker.framework/Headers" -iquote "$PODS_FRAMEWORK_BUILD_PATH/pop.framework/Headers" +OTHER_LDFLAGS = $(inherited) -ObjC -framework "FBSnapshotTestCase" -framework "PureLayout" -framework "TabBarPicker" -framework "pop" +OTHER_LIBTOOLFLAGS = $(OTHER_LDFLAGS) +OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" +PODS_FRAMEWORK_BUILD_PATH = $(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Pods-TabBarPicker_Tests +PODS_ROOT = ${SRCROOT}/Pods \ No newline at end of file diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests/Pods-TabBarPicker_Tests.modulemap b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests/Pods-TabBarPicker_Tests.modulemap new file mode 100644 index 0000000..6d807f9 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests/Pods-TabBarPicker_Tests.modulemap @@ -0,0 +1,6 @@ +framework module Pods_TabBarPicker_Tests { + umbrella header "Pods-TabBarPicker_Tests-umbrella.h" + + export * + module * { export * } +} diff --git a/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests/Pods-TabBarPicker_Tests.release.xcconfig b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests/Pods-TabBarPicker_Tests.release.xcconfig new file mode 100644 index 0000000..370c7c3 --- /dev/null +++ b/Example/Pods/Target Support Files/Pods-TabBarPicker_Tests/Pods-TabBarPicker_Tests.release.xcconfig @@ -0,0 +1,9 @@ +FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_FRAMEWORK_BUILD_PATH" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' +OTHER_CFLAGS = $(inherited) -iquote "$PODS_FRAMEWORK_BUILD_PATH/FBSnapshotTestCase.framework/Headers" -iquote "$PODS_FRAMEWORK_BUILD_PATH/PureLayout.framework/Headers" -iquote "$PODS_FRAMEWORK_BUILD_PATH/TabBarPicker.framework/Headers" -iquote "$PODS_FRAMEWORK_BUILD_PATH/pop.framework/Headers" +OTHER_LDFLAGS = $(inherited) -ObjC -framework "FBSnapshotTestCase" -framework "PureLayout" -framework "TabBarPicker" -framework "pop" +OTHER_LIBTOOLFLAGS = $(OTHER_LDFLAGS) +OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" +PODS_FRAMEWORK_BUILD_PATH = $(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Pods-TabBarPicker_Tests +PODS_ROOT = ${SRCROOT}/Pods \ No newline at end of file diff --git a/Example/Pods/pop/LICENSE b/Example/Pods/pop/LICENSE new file mode 100644 index 0000000..642126f --- /dev/null +++ b/Example/Pods/pop/LICENSE @@ -0,0 +1,30 @@ +BSD License + +For Pop software + +Copyright (c) 2014, Facebook, Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name Facebook nor the names of its contributors may be used to + endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Example/Pods/pop/README.md b/Example/Pods/pop/README.md new file mode 100644 index 0000000..e8b0215 --- /dev/null +++ b/Example/Pods/pop/README.md @@ -0,0 +1,170 @@ +![pop](https://github.com/facebook/pop/blob/master/Images/pop.gif?raw=true) + +Pop is an extensible animation engine for iOS and OS X. In addition to basic static animations, it supports spring and decay dynamic animations, making it useful for building realistic, physics-based interactions. The API allows quick integration with existing Objective-C codebases and enables the animation of any property on any object. It's a mature and well-tested framework that drives all the animations and transitions in [Paper](http://www.facebook.com/paper). + +[![Build Status](https://travis-ci.org/facebook/pop.svg)](https://travis-ci.org/facebook/pop) + +## Installation + +Pop is available on [CocoaPods](http://cocoapods.org). Just add the following to your project Podfile: + +```ruby +pod 'pop', '~> 1.0' +``` +Alternatively, you can add the project to your workspace and adopt the provided configuration files or manually copy the files under the pop subdirectory into your project. If installing manually, ensure the C++ standard library is also linked by including `-lc++` to your project linker flags. + +## Usage + +Pop adopts the Core Animation explicit animation programming model. Use by including the following import: + +```objective-c +#import +``` + +### Start, Stop & Update + +To start an animation, add it to the object you wish to animate: + +```objective-c +POPSpringAnimation *anim = [POPSpringAnimation animation]; +... +[layer pop_addAnimation:anim forKey:@"myKey"]; +``` + +To stop an animation, remove it from the object referencing the key specified on start: + +```objective-c +[layer pop_removeAnimationForKey:@"myKey"]; +``` + +The key can also be used to query for the existence of an animation. Updating the toValue of a running animation can provide the most seamless way to change course: + +```objective-c +anim = [layer pop_animationForKey:@"myKey"]; +if (anim) { + /* update to value to new destination */ + anim.toValue = @(42.0); +} else { + /* create and start a new animation */ + .... +} +``` + +While a layer was used in the above examples, the Pop interface is implemented as a category addition on NSObject. Any NSObject or subclass can be animated. + +### Types + +There are four concrete animation types: spring, decay, basic and custom. + +Spring animations can be used to give objects a delightful bounce. In this example, we use a spring animation to animate a layer's bounds from its current value to (0, 0, 400, 400): + +```objective-c +POPSpringAnimation *anim = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerBounds]; +anim.toValue = [NSValue valueWithCGRect:CGRectMake(0, 0, 400, 400)]; +[layer pop_addAnimation:anim forKey:@"size"]; +``` +Decay animations can be used to gradually slow an object to a halt. In this example, we decay a layer's positionX from it's current value and velocity 1000pts per second: + +```objective-c +POPDecayAnimation *anim = [POPDecayAnimation animationWithPropertyNamed:kPOPLayerPositionX]; +anim.velocity = @(1000.); +[layer pop_addAnimation:anim forKey:@"slide"]; +``` + +Basic animations can be used to interpolate values over a specified time period. To use an ease-in ease-out animation to animate a view's alpha from 0.0 to 1.0 over the default duration: +```objective-c +POPBasicAnimation *anim = [POPBasicAnimation animationWithPropertyNamed:kPOPViewAlpha]; +anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; +anim.fromValue = @(0.0); +anim.toValue = @(1.0); +[view pop_addAnimation:anim forKey:@"fade"]; +``` +`POPCustomAnimation` makes creating custom animations and transitions easier by handling CADisplayLink and associated time-step management. See header for more details. + + +### Properties + +The property animated is specified by the `POPAnimatableProperty` class. In this example we create a spring animation and explicitly set the animatable property corresponding to `-[CALayer bounds]`: + +```objective-c +POPSpringAnimation *anim = [POPSpringAnimation animation]; +anim.property = [POPAnimatableProperty propertyWithName:kPOPLayerBounds]; +``` + +The framework provides many common layer and view animatable properties out of box. You can animate a custom property by creating a new instance of the class. In this example, we declare a custom volume property: + +```objective-c +prop = [POPAnimatableProperty propertyWithName:@"com.foo.radio.volume" initializer:^(POPMutableAnimatableProperty *prop) { + // read value + prop.readBlock = ^(id obj, CGFloat values[]) { + values[0] = [obj volume]; + }; + // write value + prop.writeBlock = ^(id obj, const CGFloat values[]) { + [obj setVolume:values[0]]; + }; + // dynamics threshold + prop.threshold = 0.01; +}]; + +anim.property = prop; +``` + +For a complete listing of provided animatable properties, as well more information on declaring custom properties see `POPAnimatableProperty.h`. + + +### Debugging + +Here are a few tips when debugging. Pop obeys the Simulator's Toggle Slow Animations setting. Try enabling it to slow down animations and more easily observe interactions. + +Consider naming your animations. This will allow you to more easily identify them when referencing them, either via logging or in the debugger: + +```objective-c +anim.name = @"springOpen"; +``` + +Each animation comes with an associated tracer. The tracer allows you to record all animation-related events, in a fast and efficient manner, allowing you to query and analyze them after animation completion. The below example starts the tracer and configures it to log all events on animation completion: + +```objective-c +POPAnimationTracer *tracer = anim.tracer; +tracer.shouldLogAndResetOnCompletion = YES; +[tracer start]; +``` + +See `POPAnimationTracer.h` for more details. + +## Testing + +Pop has extensive unit test coverage. To install test dependencies, navigate to the root pop directory and type: + +```sh +pod install +``` + +Assuming CocoaPods is installed, this will include the necessary OCMock dependency to the unit test targets. + +## Resources + +A collection of links to external resources that may prove valuable: + +* [AGGeometryKit+POP - Animating Quadrilaterals with Pop](https://github.com/hfossli/aggeometrykit-pop) +* [Apple – Core Animation Programming Guide](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CoreAnimation_guide/Introduction/Introduction.html) +* [Codeplease – Bridging the gesture to animation gap](http://codeplease.io/playing-with-pop-ii/) +* [Codeplease – Playing with Pop (iii)](http://codeplease.io/playing-with-pop-iii/) +* [Codeplease – Adding a custom animatable property](http://codeplease.io/playing-with-pop-v/) +* [iOS Development Tips – UIScrollView-like deceleration with Pop](http://iosdevtips.co/post/84571595353/replicating-uiscrollviews-deceleration-with-facebook) +* [Pop Playground – Repository of Pop animation examples](https://github.com/callmeed/pop-playground) +* [Pop Playground 2 – Playing with Facebook's framework](http://victorbaro.com/2014/05/pop-playground-playing-with-facebooks-framework/) +* [POP-MCAnimate – Concise syntax for the Pop animation framework](https://github.com/matthewcheok/POP-MCAnimate) +* [Popping - Great examples in one project](https://github.com/schneiderandre/popping) +* [Rebound – Spring Animations for Android](http://facebook.github.io/rebound/) +* [Tapity Tutorial – Getting Started with Pop](http://tapity.com/tutorial-getting-started-with-pop/) +* [Tweaks – Easily adjust parameters for iOS apps in development](https://github.com/facebook/tweaks) +* [POP Tutorial in 5 steps](https://github.com/maxmyers/FacebookPop) + +## Contributing +See the CONTRIBUTING file for how to help out. + +## License + +Pop is released under a BSD License. See LICENSE file for details. diff --git a/Example/Pods/pop/pop/POP.h b/Example/Pods/pop/pop/POP.h new file mode 100644 index 0000000..90f4198 --- /dev/null +++ b/Example/Pods/pop/pop/POP.h @@ -0,0 +1,28 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#ifndef POP_POP_H +#define POP_POP_H + +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import + + +#endif /* POP_POP_H */ diff --git a/Example/Pods/pop/pop/POPAction.h b/Example/Pods/pop/pop/POPAction.h new file mode 100644 index 0000000..a98f394 --- /dev/null +++ b/Example/Pods/pop/pop/POPAction.h @@ -0,0 +1,66 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#ifndef POPACTION_H +#define POPACTION_H + +#import +#import + +#ifdef __cplusplus + +namespace POP { + + /** + @abstract Disables Core Animation actions using RAII. + @discussion The disablement of actions is scoped to the current transaction. + */ + class ActionDisabler + { + BOOL state; + + public: + ActionDisabler() POP_NOTHROW + { + state = [CATransaction disableActions]; + [CATransaction setDisableActions:YES]; + } + + ~ActionDisabler() + { + [CATransaction setDisableActions:state]; + } + }; + + /** + @abstract Enables Core Animation actions using RAII. + @discussion The enablement of actions is scoped to the current transaction. + */ + class ActionEnabler + { + BOOL state; + + public: + ActionEnabler() POP_NOTHROW + { + state = [CATransaction disableActions]; + [CATransaction setDisableActions:NO]; + } + + ~ActionEnabler() + { + [CATransaction setDisableActions:state]; + } + }; + +} + +#endif /* __cplusplus */ + +#endif /* POPACTION_H */ diff --git a/Example/Pods/pop/pop/POPAnimatableProperty.h b/Example/Pods/pop/pop/POPAnimatableProperty.h new file mode 100644 index 0000000..640b780 --- /dev/null +++ b/Example/Pods/pop/pop/POPAnimatableProperty.h @@ -0,0 +1,191 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#import +#import + +@class POPMutableAnimatableProperty; + +/** + @abstract Describes an animatable property. + */ +@interface POPAnimatableProperty : NSObject + +/** + @abstract Property accessor. + @param name The name of the property. + @return The animatable property with that name or nil if it does not exist. + @discussion Common animatable properties are included by default. Use the provided constants to reference. + */ ++ (id)propertyWithName:(NSString *)name; + +/** + @abstract The designated initializer. + @param name The name of the property. + @param block The block used to configure the property on creation. + @return The animatable property with name if it exists, otherwise a newly created instance configured by block. + @discussion Custom properties should use reverse-DNS naming. A newly created instance is only mutable in the scope of block. Once constructed, a property becomes immutable. + */ ++ (id)propertyWithName:(NSString *)name initializer:(void (^)(POPMutableAnimatableProperty *prop))block; + +/** + @abstract The name of the property. + @discussion Used to uniquely identify an animatable property. + */ +@property (readonly, nonatomic, copy) NSString *name; + +/** + @abstract Block used to read values from a property into an array of floats. + */ +@property (readonly, nonatomic, copy) void (^readBlock)(id obj, CGFloat values[]); + +/** + @abstract Block used to write values from an array of floats into a property. + */ +@property (readonly, nonatomic, copy) void (^writeBlock)(id obj, const CGFloat values[]); + +/** + @abstract The threshold value used when determining completion of dynamics simulations. + */ +@property (readonly, nonatomic, assign) CGFloat threshold; + +@end + +/** + @abstract A mutable animatable property intended for configuration. + */ +@interface POPMutableAnimatableProperty : POPAnimatableProperty + +/** + @abstract A read-write version of POPAnimatableProperty name property. + */ +@property (readwrite, nonatomic, copy) NSString *name; + +/** + @abstract A read-write version of POPAnimatableProperty readBlock property. + */ +@property (readwrite, nonatomic, copy) void (^readBlock)(id obj, CGFloat values[]); + +/** + @abstract A read-write version of POPAnimatableProperty writeBlock property. + */ +@property (readwrite, nonatomic, copy) void (^writeBlock)(id obj, const CGFloat values[]); + +/** + @abstract A read-write version of POPAnimatableProperty threshold property. + */ +@property (readwrite, nonatomic, assign) CGFloat threshold; + +@end + +/** + Common CALayer property names. + */ +extern NSString * const kPOPLayerBackgroundColor; +extern NSString * const kPOPLayerBounds; +extern NSString * const kPOPLayerCornerRadius; +extern NSString * const kPOPLayerBorderWidth; +extern NSString * const kPOPLayerBorderColor; +extern NSString * const kPOPLayerOpacity; +extern NSString * const kPOPLayerPosition; +extern NSString * const kPOPLayerPositionX; +extern NSString * const kPOPLayerPositionY; +extern NSString * const kPOPLayerRotation; +extern NSString * const kPOPLayerRotationX; +extern NSString * const kPOPLayerRotationY; +extern NSString * const kPOPLayerScaleX; +extern NSString * const kPOPLayerScaleXY; +extern NSString * const kPOPLayerScaleY; +extern NSString * const kPOPLayerSize; +extern NSString * const kPOPLayerSubscaleXY; +extern NSString * const kPOPLayerSubtranslationX; +extern NSString * const kPOPLayerSubtranslationXY; +extern NSString * const kPOPLayerSubtranslationY; +extern NSString * const kPOPLayerSubtranslationZ; +extern NSString * const kPOPLayerTranslationX; +extern NSString * const kPOPLayerTranslationXY; +extern NSString * const kPOPLayerTranslationY; +extern NSString * const kPOPLayerTranslationZ; +extern NSString * const kPOPLayerZPosition; +extern NSString * const kPOPLayerShadowColor; +extern NSString * const kPOPLayerShadowOffset; +extern NSString * const kPOPLayerShadowOpacity; +extern NSString * const kPOPLayerShadowRadius; + +/** + Common CAShapeLayer property names. + */ +extern NSString * const kPOPShapeLayerStrokeStart; +extern NSString * const kPOPShapeLayerStrokeEnd; +extern NSString * const kPOPShapeLayerStrokeColor; +extern NSString * const kPOPShapeLayerFillColor; + +/** + Common NSLayoutConstraint property names. + */ +extern NSString * const kPOPLayoutConstraintConstant; + + +#if TARGET_OS_IPHONE + +/** + Common UIView property names. + */ +extern NSString * const kPOPViewAlpha; +extern NSString * const kPOPViewBackgroundColor; +extern NSString * const kPOPViewBounds; +extern NSString * const kPOPViewCenter; +extern NSString * const kPOPViewFrame; +extern NSString * const kPOPViewScaleX; +extern NSString * const kPOPViewScaleXY; +extern NSString * const kPOPViewScaleY; +extern NSString * const kPOPViewSize; +extern NSString * const kPOPViewTintColor; + +/** + Common UIScrollView property names. + */ +extern NSString * const kPOPScrollViewContentOffset; +extern NSString * const kPOPScrollViewContentSize; +extern NSString * const kPOPScrollViewZoomScale; +extern NSString * const kPOPScrollViewContentInset; + +/** + Common UITableView property names. + */ +extern NSString * const kPOPTableViewContentOffset; +extern NSString * const kPOPTableViewContentSize; + +/** + Common UICollectionView property names. + */ +extern NSString * const kPOPCollectionViewContentOffset; +extern NSString * const kPOPCollectionViewContentSize; + +/** + Common UINavigationBar property names. + */ +extern NSString * const kPOPNavigationBarBarTintColor; + +/** + Common UIToolbar property names. + */ +extern NSString * const kPOPToolbarBarTintColor; + +/** + Common UITabBar property names. + */ +extern NSString * const kPOPTabBarBarTintColor; + +/** + Common UILabel property names. + */ +extern NSString * const kPOPLabelTextColor; + +#endif diff --git a/Example/Pods/pop/pop/POPAnimatableProperty.mm b/Example/Pods/pop/pop/POPAnimatableProperty.mm new file mode 100644 index 0000000..7732465 --- /dev/null +++ b/Example/Pods/pop/pop/POPAnimatableProperty.mm @@ -0,0 +1,849 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#import "POPAnimatableProperty.h" +#import "POPCGUtils.h" +#import "POPAnimationRuntime.h" + +#import + +#import + +#if TARGET_OS_IPHONE +#import +#else +#import +#endif + +// common threshold definitions +static CGFloat const kPOPThresholdColor = 0.01; +static CGFloat const kPOPThresholdPoint = 1.0; +static CGFloat const kPOPThresholdOpacity = 0.01; +static CGFloat const kPOPThresholdScale = 0.005; +static CGFloat const kPOPThresholdRotation = 0.01; +static CGFloat const kPOPThresholdRadius = 0.01; + +#pragma mark - Static + +// CALayer +NSString * const kPOPLayerBackgroundColor = @"backgroundColor"; +NSString * const kPOPLayerBounds = @"bounds"; +NSString * const kPOPLayerCornerRadius = @"cornerRadius"; +NSString * const kPOPLayerBorderWidth = @"borderWidth"; +NSString * const kPOPLayerBorderColor = @"borderColor"; +NSString * const kPOPLayerOpacity = @"opacity"; +NSString * const kPOPLayerPosition = @"position"; +NSString * const kPOPLayerPositionX = @"positionX"; +NSString * const kPOPLayerPositionY = @"positionY"; +NSString * const kPOPLayerRotation = @"rotation"; +NSString * const kPOPLayerRotationX = @"rotationX"; +NSString * const kPOPLayerRotationY = @"rotationY"; +NSString * const kPOPLayerScaleX = @"scaleX"; +NSString * const kPOPLayerScaleXY = @"scaleXY"; +NSString * const kPOPLayerScaleY = @"scaleY"; +NSString * const kPOPLayerSize = @"size"; +NSString * const kPOPLayerSubscaleXY = @"subscaleXY"; +NSString * const kPOPLayerSubtranslationX = @"subtranslationX"; +NSString * const kPOPLayerSubtranslationXY = @"subtranslationXY"; +NSString * const kPOPLayerSubtranslationY = @"subtranslationY"; +NSString * const kPOPLayerSubtranslationZ = @"subtranslationZ"; +NSString * const kPOPLayerTranslationX = @"translationX"; +NSString * const kPOPLayerTranslationXY = @"translationXY"; +NSString * const kPOPLayerTranslationY = @"translationY"; +NSString * const kPOPLayerTranslationZ = @"translationZ"; +NSString * const kPOPLayerZPosition = @"zPosition"; +NSString * const kPOPLayerShadowColor = @"shadowColor"; +NSString * const kPOPLayerShadowOffset = @"shadowOffset"; +NSString * const kPOPLayerShadowOpacity = @"shadowOpacity"; +NSString * const kPOPLayerShadowRadius = @"shadowRadius"; + +// CAShapeLayer +NSString * const kPOPShapeLayerStrokeStart = @"shapeLayer.strokeStart"; +NSString * const kPOPShapeLayerStrokeEnd = @"shapeLayer.strokeEnd"; +NSString * const kPOPShapeLayerStrokeColor = @"shapeLayer.strokeColor"; +NSString * const kPOPShapeLayerFillColor = @"shapeLayer.fillColor"; + +// NSLayoutConstraint +NSString * const kPOPLayoutConstraintConstant = @"layoutConstraint.constant"; + +// UIView +NSString * const kPOPViewAlpha = @"view.alpha"; +NSString * const kPOPViewBackgroundColor = @"view.backgroundColor"; +NSString * const kPOPViewBounds = kPOPLayerBounds; +NSString * const kPOPViewCenter = @"view.center"; +NSString * const kPOPViewFrame = @"view.frame"; +NSString * const kPOPViewScaleX = @"view.scaleX"; +NSString * const kPOPViewScaleXY = @"view.scaleXY"; +NSString * const kPOPViewScaleY = @"view.scaleY"; +NSString * const kPOPViewSize = kPOPLayerSize; +NSString * const kPOPViewTintColor = @"view.tintColor"; + +// UIScrollView +NSString * const kPOPScrollViewContentOffset = @"scrollView.contentOffset"; +NSString * const kPOPScrollViewContentSize = @"scrollView.contentSize"; +NSString * const kPOPScrollViewZoomScale = @"scrollView.zoomScale"; +NSString * const kPOPScrollViewContentInset = @"scrollView.contentInset"; + +// UITableView +NSString * const kPOPTableViewContentOffset = kPOPScrollViewContentOffset; +NSString * const kPOPTableViewContentSize = kPOPScrollViewContentSize; + +// UICollectionView +NSString * const kPOPCollectionViewContentOffset = kPOPScrollViewContentOffset; +NSString * const kPOPCollectionViewContentSize = kPOPScrollViewContentSize; + +// UINavigationBar +NSString * const kPOPNavigationBarBarTintColor = @"navigationBar.barTintColor"; + +// UIToolbar +NSString * const kPOPToolbarBarTintColor = kPOPNavigationBarBarTintColor; + +// UITabBar +NSString * const kPOPTabBarBarTintColor = kPOPNavigationBarBarTintColor; + +//UILabel +NSString * const kPOPLabelTextColor = @"label.textColor"; + +/** + State structure internal to static animatable property. + */ +typedef struct +{ + NSString *name; + pop_animatable_read_block readBlock; + pop_animatable_write_block writeBlock; + CGFloat threshold; +} _POPStaticAnimatablePropertyState; +typedef _POPStaticAnimatablePropertyState POPStaticAnimatablePropertyState; + +static POPStaticAnimatablePropertyState _staticStates[] = +{ + /* CALayer */ + + {kPOPLayerBackgroundColor, + ^(CALayer *obj, CGFloat values[]) { + POPCGColorGetRGBAComponents(obj.backgroundColor, values); + }, + ^(CALayer *obj, const CGFloat values[]) { + CGColorRef color = POPCGColorRGBACreate(values); + [obj setBackgroundColor:color]; + CGColorRelease(color); + }, + kPOPThresholdColor + }, + + {kPOPLayerBounds, + ^(CALayer *obj, CGFloat values[]) { + values_from_rect(values, [obj bounds]); + }, + ^(CALayer *obj, const CGFloat values[]) { + [obj setBounds:values_to_rect(values)]; + }, + kPOPThresholdPoint + }, + + {kPOPLayerCornerRadius, + ^(CALayer *obj, CGFloat values[]) { + values[0] = [obj cornerRadius]; + }, + ^(CALayer *obj, const CGFloat values[]) { + [obj setCornerRadius:values[0]]; + }, + kPOPThresholdRadius + }, + + {kPOPLayerBorderWidth, + ^(CALayer *obj, CGFloat values[]) { + values[0] = [obj borderWidth]; + }, + ^(CALayer *obj, const CGFloat values[]) { + [obj setBorderWidth:values[0]]; + }, + 0.01 + }, + + {kPOPLayerBorderColor, + ^(CALayer *obj, CGFloat values[]) { + POPCGColorGetRGBAComponents(obj.borderColor, values); + }, + ^(CALayer *obj, const CGFloat values[]) { + CGColorRef color = POPCGColorRGBACreate(values); + [obj setBorderColor:color]; + CGColorRelease(color); + }, + kPOPThresholdColor + }, + + {kPOPLayerPosition, + ^(CALayer *obj, CGFloat values[]) { + values_from_point(values, [(CALayer *)obj position]); + }, + ^(CALayer *obj, const CGFloat values[]) { + [obj setPosition:values_to_point(values)]; + }, + kPOPThresholdPoint + }, + + {kPOPLayerPositionX, + ^(CALayer *obj, CGFloat values[]) { + values[0] = [(CALayer *)obj position].x; + }, + ^(CALayer *obj, const CGFloat values[]) { + CGPoint p = [(CALayer *)obj position]; + p.x = values[0]; + [obj setPosition:p]; + }, + kPOPThresholdPoint + }, + + {kPOPLayerPositionY, + ^(CALayer *obj, CGFloat values[]) { + values[0] = [(CALayer *)obj position].y; + }, + ^(CALayer *obj, const CGFloat values[]) { + CGPoint p = [(CALayer *)obj position]; + p.y = values[0]; + [obj setPosition:p]; + }, + kPOPThresholdPoint + }, + + {kPOPLayerOpacity, + ^(CALayer *obj, CGFloat values[]) { + values[0] = [obj opacity]; + }, + ^(CALayer *obj, const CGFloat values[]) { + [obj setOpacity:((float)values[0])]; + }, + kPOPThresholdOpacity + }, + + {kPOPLayerScaleX, + ^(CALayer *obj, CGFloat values[]) { + values[0] = POPLayerGetScaleX(obj); + }, + ^(CALayer *obj, const CGFloat values[]) { + POPLayerSetScaleX(obj, values[0]); + }, + kPOPThresholdScale + }, + + {kPOPLayerScaleY, + ^(CALayer *obj, CGFloat values[]) { + values[0] = POPLayerGetScaleY(obj); + }, + ^(CALayer *obj, const CGFloat values[]) { + POPLayerSetScaleY(obj, values[0]); + }, + kPOPThresholdScale + }, + + {kPOPLayerScaleXY, + ^(CALayer *obj, CGFloat values[]) { + values_from_point(values, POPLayerGetScaleXY(obj)); + }, + ^(CALayer *obj, const CGFloat values[]) { + POPLayerSetScaleXY(obj, values_to_point(values)); + }, + kPOPThresholdScale + }, + + {kPOPLayerSubscaleXY, + ^(CALayer *obj, CGFloat values[]) { + values_from_point(values, POPLayerGetSubScaleXY(obj)); + }, + ^(CALayer *obj, const CGFloat values[]) { + POPLayerSetSubScaleXY(obj, values_to_point(values)); + }, + kPOPThresholdScale + }, + + {kPOPLayerTranslationX, + ^(CALayer *obj, CGFloat values[]) { + values[0] = POPLayerGetTranslationX(obj); + }, + ^(CALayer *obj, const CGFloat values[]) { + POPLayerSetTranslationX(obj, values[0]); + }, + kPOPThresholdPoint + }, + + {kPOPLayerTranslationY, + ^(CALayer *obj, CGFloat values[]) { + values[0] = POPLayerGetTranslationY(obj); + }, + ^(CALayer *obj, const CGFloat values[]) { + POPLayerSetTranslationY(obj, values[0]); + }, + kPOPThresholdPoint + }, + + {kPOPLayerTranslationZ, + ^(CALayer *obj, CGFloat values[]) { + values[0] = POPLayerGetTranslationZ(obj); + }, + ^(CALayer *obj, const CGFloat values[]) { + POPLayerSetTranslationZ(obj, values[0]); + }, + kPOPThresholdPoint + }, + + {kPOPLayerTranslationXY, + ^(CALayer *obj, CGFloat values[]) { + values_from_point(values, POPLayerGetTranslationXY(obj)); + }, + ^(CALayer *obj, const CGFloat values[]) { + POPLayerSetTranslationXY(obj, values_to_point(values)); + }, + kPOPThresholdPoint + }, + + {kPOPLayerSubtranslationX, + ^(CALayer *obj, CGFloat values[]) { + values[0] = POPLayerGetSubTranslationX(obj); + }, + ^(CALayer *obj, const CGFloat values[]) { + POPLayerSetSubTranslationX(obj, values[0]); + }, + kPOPThresholdPoint + }, + + {kPOPLayerSubtranslationY, + ^(CALayer *obj, CGFloat values[]) { + values[0] = POPLayerGetSubTranslationY(obj); + }, + ^(CALayer *obj, const CGFloat values[]) { + POPLayerSetSubTranslationY(obj, values[0]); + }, + kPOPThresholdPoint + }, + + {kPOPLayerSubtranslationZ, + ^(CALayer *obj, CGFloat values[]) { + values[0] = POPLayerGetSubTranslationZ(obj); + }, + ^(CALayer *obj, const CGFloat values[]) { + POPLayerSetSubTranslationZ(obj, values[0]); + }, + kPOPThresholdPoint + }, + + {kPOPLayerSubtranslationXY, + ^(CALayer *obj, CGFloat values[]) { + values_from_point(values, POPLayerGetSubTranslationXY(obj)); + }, + ^(CALayer *obj, const CGFloat values[]) { + POPLayerSetSubTranslationXY(obj, values_to_point(values)); + }, + kPOPThresholdPoint + }, + + {kPOPLayerZPosition, + ^(CALayer *obj, CGFloat values[]) { + values[0] = [obj zPosition]; + }, + ^(CALayer *obj, const CGFloat values[]) { + [obj setZPosition:values[0]]; + }, + kPOPThresholdPoint + }, + + {kPOPLayerSize, + ^(CALayer *obj, CGFloat values[]) { + values_from_size(values, [obj bounds].size); + }, + ^(CALayer *obj, const CGFloat values[]) { + CGSize size = values_to_size(values); + if (size.width < 0. || size.height < 0.) + return; + + CGRect b = [obj bounds]; + b.size = size; + [obj setBounds:b]; + }, + kPOPThresholdPoint + }, + + {kPOPLayerRotation, + ^(CALayer *obj, CGFloat values[]) { + values[0] = POPLayerGetRotation(obj); + }, + ^(CALayer *obj, const CGFloat values[]) { + POPLayerSetRotation(obj, values[0]); + }, + kPOPThresholdRotation + }, + + {kPOPLayerRotationY, + ^(CALayer *obj, CGFloat values[]) { + values[0] = POPLayerGetRotationY(obj); + }, + ^(id obj, const CGFloat values[]) { + POPLayerSetRotationY(obj, values[0]); + }, + kPOPThresholdRotation + }, + + {kPOPLayerRotationX, + ^(CALayer *obj, CGFloat values[]) { + values[0] = POPLayerGetRotationX(obj); + }, + ^(CALayer *obj, const CGFloat values[]) { + POPLayerSetRotationX(obj, values[0]); + }, + kPOPThresholdRotation + }, + + {kPOPLayerShadowColor, + ^(CALayer *obj, CGFloat values[]) { + POPCGColorGetRGBAComponents(obj.shadowColor, values); + }, + ^(CALayer *obj, const CGFloat values[]) { + CGColorRef color = POPCGColorRGBACreate(values); + [obj setShadowColor:color]; + CGColorRelease(color); + }, + 0.01 + }, + + {kPOPLayerShadowOffset, + ^(CALayer *obj, CGFloat values[]) { + values_from_size(values, [obj shadowOffset]); + }, + ^(CALayer *obj, const CGFloat values[]) { + CGSize size = values_to_size(values); + [obj setShadowOffset:size]; + }, + 0.01 + }, + + {kPOPLayerShadowOpacity, + ^(CALayer *obj, CGFloat values[]) { + values[0] = [obj shadowOpacity]; + }, + ^(CALayer *obj, const CGFloat values[]) { + [obj setShadowOpacity:values[0]]; + }, + kPOPThresholdOpacity + }, + + {kPOPLayerShadowRadius, + ^(CALayer *obj, CGFloat values[]) { + values[0] = [obj shadowRadius]; + }, + ^(CALayer *obj, const CGFloat values[]) { + [obj setShadowRadius:values[0]]; + }, + kPOPThresholdRadius + }, + + /* CAShapeLayer */ + + {kPOPShapeLayerStrokeStart, + ^(CAShapeLayer *obj, CGFloat values[]) { + values[0] = obj.strokeStart; + }, + ^(CAShapeLayer *obj, const CGFloat values[]) { + obj.strokeStart = values[0]; + }, + 0.01 + }, + + {kPOPShapeLayerStrokeEnd, + ^(CAShapeLayer *obj, CGFloat values[]) { + values[0] = obj.strokeEnd; + }, + ^(CAShapeLayer *obj, const CGFloat values[]) { + obj.strokeEnd = values[0]; + }, + 0.01 + }, + + {kPOPShapeLayerStrokeColor, + ^(CAShapeLayer *obj, CGFloat values[]) { + POPCGColorGetRGBAComponents(obj.strokeColor, values); + }, + ^(CAShapeLayer *obj, const CGFloat values[]) { + CGColorRef color = POPCGColorRGBACreate(values); + [obj setStrokeColor:color]; + CGColorRelease(color); + }, + kPOPThresholdColor + }, + + {kPOPShapeLayerFillColor, + ^(CAShapeLayer *obj, CGFloat values[]) { + POPCGColorGetRGBAComponents(obj.fillColor, values); + }, + ^(CAShapeLayer *obj, const CGFloat values[]) { + CGColorRef color = POPCGColorRGBACreate(values); + [obj setFillColor:color]; + CGColorRelease(color); + }, + kPOPThresholdColor + }, + + {kPOPLayoutConstraintConstant, + ^(NSLayoutConstraint *obj, CGFloat values[]) { + values[0] = obj.constant; + }, + ^(NSLayoutConstraint *obj, const CGFloat values[]) { + obj.constant = values[0]; + }, + 0.01 + }, + +#if TARGET_OS_IPHONE + + /* UIView */ + + {kPOPViewAlpha, + ^(UIView *obj, CGFloat values[]) { + values[0] = obj.alpha; + }, + ^(UIView *obj, const CGFloat values[]) { + obj.alpha = values[0]; + }, + kPOPThresholdOpacity + }, + + {kPOPViewBackgroundColor, + ^(UIView *obj, CGFloat values[]) { + POPUIColorGetRGBAComponents(obj.backgroundColor, values); + }, + ^(UIView *obj, const CGFloat values[]) { + obj.backgroundColor = POPUIColorRGBACreate(values); + }, + kPOPThresholdColor + }, + + {kPOPViewCenter, + ^(UIView *obj, CGFloat values[]) { + values_from_point(values, obj.center); + }, + ^(UIView *obj, const CGFloat values[]) { + obj.center = values_to_point(values); + }, + kPOPThresholdPoint + }, + + {kPOPViewFrame, + ^(UIView *obj, CGFloat values[]) { + values_from_rect(values, obj.frame); + }, + ^(UIView *obj, const CGFloat values[]) { + obj.frame = values_to_rect(values); + }, + kPOPThresholdPoint + }, + + {kPOPViewScaleX, + ^(UIView *obj, CGFloat values[]) { + values[0] = POPLayerGetScaleX(obj.layer); + }, + ^(UIView *obj, const CGFloat values[]) { + POPLayerSetScaleX(obj.layer, values[0]); + }, + kPOPThresholdScale + }, + + {kPOPViewScaleY, + ^(UIView *obj, CGFloat values[]) { + values[0] = POPLayerGetScaleY(obj.layer); + }, + ^(UIView *obj, const CGFloat values[]) { + POPLayerSetScaleY(obj.layer, values[0]); + }, + kPOPThresholdScale + }, + + {kPOPViewScaleXY, + ^(UIView *obj, CGFloat values[]) { + values_from_point(values, POPLayerGetScaleXY(obj.layer)); + }, + ^(UIView *obj, const CGFloat values[]) { + POPLayerSetScaleXY(obj.layer, values_to_point(values)); + }, + kPOPThresholdScale + }, + + {kPOPViewTintColor, + ^(UIView *obj, CGFloat values[]) { + POPUIColorGetRGBAComponents(obj.tintColor, values); + }, + ^(UIView *obj, const CGFloat values[]) { + obj.tintColor = POPUIColorRGBACreate(values); + }, + kPOPThresholdColor + }, + + /* UIScrollView */ + + {kPOPScrollViewContentOffset, + ^(UIScrollView *obj, CGFloat values[]) { + values_from_point(values, obj.contentOffset); + }, + ^(UIScrollView *obj, const CGFloat values[]) { + [obj setContentOffset:values_to_point(values) animated:NO]; + }, + kPOPThresholdPoint + }, + + {kPOPScrollViewContentSize, + ^(UIScrollView *obj, CGFloat values[]) { + values_from_size(values, obj.contentSize); + }, + ^(UIScrollView *obj, const CGFloat values[]) { + obj.contentSize = values_to_size(values); + }, + kPOPThresholdPoint + }, + + {kPOPScrollViewZoomScale, + ^(UIScrollView *obj, CGFloat values[]) { + values[0]=obj.zoomScale; + }, + ^(UIScrollView *obj, const CGFloat values[]) { + obj.zoomScale=values[0]; + }, + kPOPThresholdScale + }, + + {kPOPScrollViewContentInset, + ^(UIScrollView *obj, CGFloat values[]) { + values[0] = obj.contentInset.top; + values[1] = obj.contentInset.left; + values[2] = obj.contentInset.bottom; + values[3] = obj.contentInset.right; + }, + ^(UIScrollView *obj, const CGFloat values[]) { + obj.contentInset = values_to_edge_insets(values); + }, + kPOPThresholdPoint + }, + + /* UINavigationBar */ + + {kPOPNavigationBarBarTintColor, + ^(UINavigationBar *obj, CGFloat values[]) { + POPUIColorGetRGBAComponents(obj.barTintColor, values); + }, + ^(UINavigationBar *obj, const CGFloat values[]) { + obj.barTintColor = POPUIColorRGBACreate(values); + }, + kPOPThresholdColor + }, + + /* UILabel */ + + {kPOPLabelTextColor, + ^(UILabel *obj, CGFloat values[]) { + POPUIColorGetRGBAComponents(obj.textColor, values); + }, + ^(UILabel *obj, const CGFloat values[]) { + obj.textColor = POPUIColorRGBACreate(values); + }, + kPOPThresholdColor + }, + +#endif + +}; + +static NSUInteger staticIndexWithName(NSString *aName) +{ + NSUInteger idx = 0; + + while (idx < POP_ARRAY_COUNT(_staticStates)) { + if ([_staticStates[idx].name isEqualToString:aName]) + return idx; + idx++; + } + + return NSNotFound; +} + +/** + Concrete static property class. + */ +@interface POPStaticAnimatableProperty : POPAnimatableProperty +{ +@public + POPStaticAnimatablePropertyState *_state; +} +@end + +@implementation POPStaticAnimatableProperty + +- (NSString *)name +{ + return _state->name; +} + +- (pop_animatable_read_block)readBlock +{ + return _state->readBlock; +} + +- (pop_animatable_write_block)writeBlock +{ + return _state->writeBlock; +} + +- (CGFloat)threshold +{ + return _state->threshold; +} + +@end + +#pragma mark - Concrete + +/** + Concrete immutable property class. + */ +@interface POPConcreteAnimatableProperty : POPAnimatableProperty +- (instancetype)initWithName:(NSString *)name readBlock:(pop_animatable_read_block)read writeBlock:(pop_animatable_write_block)write threshold:(CGFloat)threshold; +@end + +@implementation POPConcreteAnimatableProperty + +// default synthesis +@synthesize name, readBlock, writeBlock, threshold; + +- (instancetype)initWithName:(NSString *)aName readBlock:(pop_animatable_read_block)aReadBlock writeBlock:(pop_animatable_write_block)aWriteBlock threshold:(CGFloat)aThreshold +{ + self = [super init]; + if (nil != self) { + name = [aName copy]; + readBlock = [aReadBlock copy]; + writeBlock = [aWriteBlock copy]; + threshold = aThreshold; + } + return self; +} +@end + +#pragma mark - Mutable + +@implementation POPMutableAnimatableProperty + +// default synthesis +@synthesize name, readBlock, writeBlock, threshold; + +@end + +#pragma mark - Cluster + +/** + Singleton placeholder property class to support class cluster. + */ +@interface POPPlaceholderAnimatableProperty : POPAnimatableProperty + +@end + +@implementation POPPlaceholderAnimatableProperty + +// default synthesis +@synthesize name, readBlock, writeBlock, threshold; + +@end + +/** + Cluster class. + */ +@implementation POPAnimatableProperty + +// avoid creating backing ivars +@dynamic name, readBlock, writeBlock, threshold; + +static POPAnimatableProperty *placeholder = nil; + ++ (void)initialize +{ + if (self == [POPAnimatableProperty class]) { + placeholder = [POPPlaceholderAnimatableProperty alloc]; + } +} + ++ (id)allocWithZone:(struct _NSZone *)zone +{ + if (self == [POPAnimatableProperty class]) { + if (nil == placeholder) { + placeholder = [super allocWithZone:zone]; + } + return placeholder; + } + return [super allocWithZone:zone]; +} + +- (id)copyWithZone:(NSZone *)zone +{ + if ([self isKindOfClass:[POPMutableAnimatableProperty class]]) { + POPConcreteAnimatableProperty *copyProperty = [[POPConcreteAnimatableProperty alloc] initWithName:self.name readBlock:self.readBlock writeBlock:self.writeBlock threshold:self.threshold]; + return copyProperty; + } else { + return self; + } +} + +- (id)mutableCopyWithZone:(NSZone *)zone +{ + POPMutableAnimatableProperty *copyProperty = [[POPMutableAnimatableProperty alloc] init]; + copyProperty.name = self.name; + copyProperty.readBlock = self.readBlock; + copyProperty.writeBlock = self.writeBlock; + copyProperty.threshold = self.threshold; + return copyProperty; +} + ++ (id)propertyWithName:(NSString *)aName +{ + return [self propertyWithName:aName initializer:NULL]; +} + ++ (id)propertyWithName:(NSString *)aName initializer:(void (^)(POPMutableAnimatableProperty *prop))aBlock +{ + POPAnimatableProperty *prop = nil; + + static NSMutableDictionary *_propertyDict = nil; + if (nil == _propertyDict) { + _propertyDict = [[NSMutableDictionary alloc] initWithCapacity:10]; + } + + prop = _propertyDict[aName]; + if (nil != prop) { + return prop; + } + + NSUInteger staticIdx = staticIndexWithName(aName); + + if (NSNotFound != staticIdx) { + POPStaticAnimatableProperty *staticProp = [[POPStaticAnimatableProperty alloc] init]; + staticProp->_state = &_staticStates[staticIdx]; + _propertyDict[aName] = staticProp; + prop = staticProp; + } else if (NULL != aBlock) { + POPMutableAnimatableProperty *mutableProp = [[POPMutableAnimatableProperty alloc] init]; + mutableProp.name = aName; + mutableProp.threshold = 1.0; + aBlock(mutableProp); + prop = [mutableProp copy]; + } + + return prop; +} + +- (NSString *)description +{ + NSMutableString *s = [NSMutableString stringWithFormat:@"%@ name:%@ threshold:%f", super.description, self.name, self.threshold]; + return s; +} + +@end diff --git a/Example/Pods/pop/pop/POPAnimation.h b/Example/Pods/pop/pop/POPAnimation.h new file mode 100644 index 0000000..a79bf17 --- /dev/null +++ b/Example/Pods/pop/pop/POPAnimation.h @@ -0,0 +1,162 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#import + +#import +#import + +@class CAMediaTimingFunction; + +/** + @abstract The abstract animation base class. + @discussion Instantiate and use one of the concrete animation subclasses. + */ +@interface POPAnimation : NSObject + +/** + @abstract The name of the animation. + @discussion Optional property to help identify the animation. + */ +@property (copy, nonatomic) NSString *name; + +/** + @abstract The beginTime of the animation in media time. + @discussion Defaults to 0 and starts immediately. + */ +@property (assign, nonatomic) CFTimeInterval beginTime; + +/** + @abstract The animation delegate. + @discussion See {@ref POPAnimationDelegate} for details. + */ +@property (weak, nonatomic) id delegate; + +/** + @abstract The animation tracer. + @discussion Returns the existing tracer, creating one if needed. Call start/stop on the tracer to toggle event collection. + */ +@property (readonly, nonatomic) POPAnimationTracer *tracer; + +/** + @abstract Optional block called on animation completion. + */ +@property (copy, nonatomic) void (^completionBlock)(POPAnimation *anim, BOOL finished); + +/** + @abstract Flag indicating whether animation should be removed on completion. + @discussion Setting to NO can facilitate animation reuse. Defaults to YES. + */ +@property (assign, nonatomic) BOOL removedOnCompletion; + +/** + @abstract Flag indicating whether animation is paused. + @discussion A paused animation is excluded from the list of active animations. On initial creation, defaults to YES. On animation addition, the animation is implicity unpaused. On animation completion, the animation is implicity paused including for animations with removedOnCompletion set to NO. + */ +@property (assign, nonatomic, getter = isPaused) BOOL paused; + +/** + @abstract Flag indicating whether animation autoreverses. + @discussion An animation that autoreverses will have twice the duration before it is considered finished. It will animate to the toValue, stop, then animate back to the original fromValue. The delegate methods are called as follows: + + 1) animationDidStart: is called at the beginning, as usual, and then after each toValue is reached and the autoreverse is going to start. + 2) animationDidReachToValue: is called every time the toValue is reached. The toValue is swapped with the fromValue at the end of each animation segment. This means that with autoreverses set to YES, the animationDidReachToValue: delegate method will be called a minimum of twice. + 3) animationDidStop:finished: is called every time the toValue is reached, the finished argument will be NO if the autoreverse is not yet complete. + */ +@property (assign, nonatomic) BOOL autoreverses; + +/** + @abstract The number of times to repeat the animation. + @discussion A repeatCount of 0 or 1 means that the animation will not repeat, just like Core Animation. A repeatCount of 2 or greater means that the animation will run that many times before stopping. The delegate methods are called as follows: + + 1) animationDidStart: is called at the beginning of each animation repeat. + 2) animationDidReachToValue: is called every time the toValue is reached. + 3) animationDidStop:finished: is called every time the toValue is reached, the finished argument will be NO if the autoreverse is not yet complete. + +When combined with the autoreverses property, a singular animation is effectively twice as long. + */ +@property (assign, nonatomic) NSInteger repeatCount; + +/** + @abstract Repeat the animation forever. + @discussion This property will make the animation repeat forever. The value of the repeatCount property is undefined when this property is set. The finished parameter of the delegate callback animationDidStop:finished: will always be NO. + */ +@property (assign, nonatomic) BOOL repeatForever; + +@end + +/** + @abstract The animation delegate. + */ +@protocol POPAnimationDelegate +@optional + +/** + @abstract Called on animation start. + @param anim The relevant animation. + */ +- (void)pop_animationDidStart:(POPAnimation *)anim; + +/** + @abstract Called when value meets or exceeds to value. + @param anim The relevant animation. + */ +- (void)pop_animationDidReachToValue:(POPAnimation *)anim; + +/** + @abstract Called on animation stop. + @param anim The relevant animation. + @param finished Flag indicating finished state. Flag is true if the animation reached completion before being removed. + */ +- (void)pop_animationDidStop:(POPAnimation *)anim finished:(BOOL)finished; + +/** + @abstract Called each frame animation is applied. + @param anim The relevant animation. + */ +- (void)pop_animationDidApply:(POPAnimation *)anim; + +@end + + +@interface NSObject (POP) + +/** + @abstract Add an animation to the reciver. + @param anim The animation to add. + @param key The key used to identify the animation. + @discussion The 'key' may be any string such that only one animation per unique key is added per object. + */ +- (void)pop_addAnimation:(POPAnimation *)anim forKey:(NSString *)key; + +/** + @abstract Remove all animations attached to the receiver. + */ +- (void)pop_removeAllAnimations; + +/** + @abstract Remove any animation attached to the receiver for 'key'. + @param key The key used to identify the animation. + */ +- (void)pop_removeAnimationForKey:(NSString *)key; + +/** + @abstract Returns an array containing the keys of all animations currently attached to the receiver. + @param The order of keys reflects the order in which animations will be applied. + */ +- (NSArray *)pop_animationKeys; + +/** + @abstract Returns any animation attached to the receiver. + @param key The key used to identify the animation. + @returns The animation currently attached, or nil if no such animation exists. + */ +- (id)pop_animationForKey:(NSString *)key; + +@end diff --git a/Example/Pods/pop/pop/POPAnimation.mm b/Example/Pods/pop/pop/POPAnimation.mm new file mode 100644 index 0000000..99b0e8e --- /dev/null +++ b/Example/Pods/pop/pop/POPAnimation.mm @@ -0,0 +1,269 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#import "POPAnimationInternal.h" +#import "POPAnimationTracerInternal.h" + +#import + +#import "POPAnimationExtras.h" +#import "POPAnimationRuntime.h" +#import "POPAnimatorPrivate.h" +#import "POPAction.h" + +using namespace POP; + +#pragma mark - POPAnimation + +@implementation POPAnimation +@synthesize solver = _solver; +@synthesize currentValue = _currentValue; +@synthesize progressMarkers = _progressMarkers; + +#pragma mark - Lifecycle + +- (id)init +{ + [NSException raise:NSStringFromClass([self class]) format:@"Attempting to instantiate an abstract class. Use a concrete subclass instead."]; + return nil; +} + +- (id)_init +{ + self = [super init]; + if (nil != self) { + [self _initState]; + } + return self; +} + +- (void)_initState +{ + _state = new POPAnimationState(self); +} + +- (void)dealloc +{ + if (_state) { + delete _state; + _state = NULL; + }; +} + +#pragma mark - Properties + +- (id)delegate +{ + return _state->delegate; +} + +- (void)setDelegate:(id)delegate +{ + _state->setDelegate(delegate); +} + +- (BOOL)isPaused +{ + return _state->paused; +} + +- (void)setPaused:(BOOL)paused +{ + _state->setPaused(paused ? true : false); +} + +- (NSInteger)repeatCount +{ + if (_state->autoreverses) { + return _state->repeatCount / 2; + } else { + return _state->repeatCount; + } +} + +- (void)setRepeatCount:(NSInteger)repeatCount +{ + if (repeatCount > 0) { + if (repeatCount > NSIntegerMax / 2) { + repeatCount = NSIntegerMax / 2; + } + + if (_state->autoreverses) { + _state->repeatCount = (repeatCount * 2); + } else { + _state->repeatCount = repeatCount; + } + } +} + +- (BOOL)autoreverses +{ + return _state->autoreverses; +} + +- (void)setAutoreverses:(BOOL)autoreverses +{ + _state->autoreverses = autoreverses; + if (autoreverses) { + if (_state->repeatCount == 0) { + [self setRepeatCount:1]; + } + } +} + +FB_PROPERTY_GET(POPAnimationState, type, POPAnimationType); +DEFINE_RW_PROPERTY_OBJ_COPY(POPAnimationState, completionBlock, setCompletionBlock:, POPAnimationCompletionBlock); +DEFINE_RW_PROPERTY_OBJ_COPY(POPAnimationState, name, setName:, NSString*); +DEFINE_RW_PROPERTY(POPAnimationState, beginTime, setBeginTime:, CFTimeInterval); +DEFINE_RW_FLAG(POPAnimationState, removedOnCompletion, removedOnCompletion, setRemovedOnCompletion:); +DEFINE_RW_FLAG(POPAnimationState, repeatForever, repeatForever, setRepeatForever:); + +- (id)valueForUndefinedKey:(NSString *)key +{ + return _state->dict[key]; +} + +- (void)setValue:(id)value forUndefinedKey:(NSString *)key +{ + if (!value) { + [_state->dict removeObjectForKey:key]; + } else { + if (!_state->dict) + _state->dict = [[NSMutableDictionary alloc] init]; + _state->dict[key] = value; + } +} + +- (POPAnimationTracer *)tracer +{ + if (!_state->tracer) { + _state->tracer = [[POPAnimationTracer alloc] initWithAnimation:self]; + } + return _state->tracer; +} + +- (NSString *)description +{ + NSMutableString *s = [NSMutableString stringWithFormat:@"<%@:%p", NSStringFromClass([self class]), self]; + [self _appendDescription:s debug:NO]; + [s appendString:@">"]; + return s; +} + +- (NSString *)debugDescription +{ + NSMutableString *s = [NSMutableString stringWithFormat:@"<%@:%p", NSStringFromClass([self class]), self]; + [self _appendDescription:s debug:YES]; + [s appendString:@">"]; + return s; +} + +#pragma mark - Utility + +POPAnimationState *POPAnimationGetState(POPAnimation *a) +{ + return a->_state; +} + +- (BOOL)_advance:(id)object currentTime:(CFTimeInterval)currentTime elapsedTime:(CFTimeInterval)elapsedTime +{ + return YES; +} + +- (void)_appendDescription:(NSMutableString *)s debug:(BOOL)debug +{ + if (_state->name) + [s appendFormat:@"; name = %@", _state->name]; + + if (!self.removedOnCompletion) + [s appendFormat:@"; removedOnCompletion = %@", POPStringFromBOOL(self.removedOnCompletion)]; + + if (debug) { + if (_state->active) + [s appendFormat:@"; active = %@", POPStringFromBOOL(_state->active)]; + + if (_state->paused) + [s appendFormat:@"; paused = %@", POPStringFromBOOL(_state->paused)]; + } + + if (_state->beginTime) { + [s appendFormat:@"; beginTime = %f", _state->beginTime]; + } + + for (NSString *key in _state->dict) { + [s appendFormat:@"; %@ = %@", key, _state->dict[key]]; + } +} + +@end + + +#pragma mark - POPPropertyAnimation + +#pragma mark - POPBasicAnimation + +#pragma mark - POPDecayAnimation + +@implementation NSObject (POP) + +- (void)pop_addAnimation:(POPAnimation *)anim forKey:(NSString *)key +{ + [[POPAnimator sharedAnimator] addAnimation:anim forObject:self key:key]; +} + +- (void)pop_removeAllAnimations +{ + [[POPAnimator sharedAnimator] removeAllAnimationsForObject:self]; +} + +- (void)pop_removeAnimationForKey:(NSString *)key +{ + [[POPAnimator sharedAnimator] removeAnimationForObject:self key:key]; +} + +- (NSArray *)pop_animationKeys +{ + return [[POPAnimator sharedAnimator] animationKeysForObject:self]; +} + +- (id)pop_animationForKey:(NSString *)key +{ + return [[POPAnimator sharedAnimator] animationForObject:self key:key]; +} + +@end + +@implementation NSProxy (POP) + +- (void)pop_addAnimation:(POPAnimation *)anim forKey:(NSString *)key +{ + [[POPAnimator sharedAnimator] addAnimation:anim forObject:self key:key]; +} + +- (void)pop_removeAllAnimations +{ + [[POPAnimator sharedAnimator] removeAllAnimationsForObject:self]; +} + +- (void)pop_removeAnimationForKey:(NSString *)key +{ + [[POPAnimator sharedAnimator] removeAnimationForObject:self key:key]; +} + +- (NSArray *)pop_animationKeys +{ + return [[POPAnimator sharedAnimator] animationKeysForObject:self]; +} + +- (id)pop_animationForKey:(NSString *)key +{ + return [[POPAnimator sharedAnimator] animationForObject:self key:key]; +} + +@end diff --git a/Example/Pods/pop/pop/POPAnimationEvent.h b/Example/Pods/pop/pop/POPAnimationEvent.h new file mode 100644 index 0000000..e761091 --- /dev/null +++ b/Example/Pods/pop/pop/POPAnimationEvent.h @@ -0,0 +1,69 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#import + +/** + @abstract Enumeraton of animation event types. + */ +typedef NS_ENUM(NSUInteger, POPAnimationEventType) { + kPOPAnimationEventPropertyRead = 0, + kPOPAnimationEventPropertyWrite, + kPOPAnimationEventToValueUpdate, + kPOPAnimationEventFromValueUpdate, + kPOPAnimationEventVelocityUpdate, + kPOPAnimationEventBouncinessUpdate, + kPOPAnimationEventSpeedUpdate, + kPOPAnimationEventFrictionUpdate, + kPOPAnimationEventMassUpdate, + kPOPAnimationEventTensionUpdate, + kPOPAnimationEventDidStart, + kPOPAnimationEventDidStop, + kPOPAnimationEventDidReachToValue, + kPOPAnimationEventAutoreversed +}; + +/** + @abstract The base animation event class. + */ +@interface POPAnimationEvent : NSObject + +/** + @abstract The event type. See {@ref POPAnimationEventType} for possible values. + */ +@property (readonly, nonatomic, assign) POPAnimationEventType type; + +/** + @abstract The time of event. + */ +@property (readonly, nonatomic, assign) CFTimeInterval time; + +/** + @abstract Optional string describing the animation at time of event. + */ +@property (readonly, nonatomic, copy) NSString *animationDescription; + +@end + +/** + @abstract An animation event subclass for recording value and velocity. + */ +@interface POPAnimationValueEvent : POPAnimationEvent + +/** + @abstract The value recorded. + */ +@property (readonly, nonatomic, strong) id value; + +/** + @abstract The velocity recorded, if any. + */ +@property (readonly, nonatomic, strong) id velocity; + +@end diff --git a/Example/Pods/pop/pop/POPAnimationEvent.mm b/Example/Pods/pop/pop/POPAnimationEvent.mm new file mode 100644 index 0000000..d3a13b6 --- /dev/null +++ b/Example/Pods/pop/pop/POPAnimationEvent.mm @@ -0,0 +1,108 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#import "POPAnimationEvent.h" +#import "POPAnimationEventInternal.h" + +static NSString *stringFromType(POPAnimationEventType aType) +{ + switch (aType) { + case kPOPAnimationEventPropertyRead: + return @"read"; + case kPOPAnimationEventPropertyWrite: + return @"write"; + case kPOPAnimationEventToValueUpdate: + return @"toValue"; + case kPOPAnimationEventFromValueUpdate: + return @"fromValue"; + case kPOPAnimationEventVelocityUpdate: + return @"velocity"; + case kPOPAnimationEventSpeedUpdate: + return @"speed"; + case kPOPAnimationEventBouncinessUpdate: + return @"bounciness"; + case kPOPAnimationEventFrictionUpdate: + return @"friction"; + case kPOPAnimationEventMassUpdate: + return @"mass"; + case kPOPAnimationEventTensionUpdate: + return @"tension"; + case kPOPAnimationEventDidStart: + return @"didStart"; + case kPOPAnimationEventDidStop: + return @"didStop"; + case kPOPAnimationEventDidReachToValue: + return @"didReachToValue"; + case kPOPAnimationEventAutoreversed: + return @"autoreversed"; + default: + return nil; + } +} + +@implementation POPAnimationEvent +@synthesize type = _type; +@synthesize time = _time; +@synthesize animationDescription = _animationDescription; + +- (instancetype)initWithType:(POPAnimationEventType)aType time:(CFTimeInterval)aTime +{ + self = [super init]; + if (nil != self) { + _type = aType; + _time = aTime; + } + return self; +} + +- (NSString *)description +{ + NSMutableString *s = [NSMutableString stringWithFormat:@""]; + return s; +} + +// subclass override +- (void)_appendDescription:(NSMutableString *)s +{ + if (0 != _animationDescription.length) { + [s appendFormat:@"; animation = %@", _animationDescription]; + } +} + +@end + +@implementation POPAnimationValueEvent +@synthesize value = _value; +@synthesize velocity = _velocity; + +- (instancetype)initWithType:(POPAnimationEventType)aType time:(CFTimeInterval)aTime value:(id)aValue +{ + self = [self initWithType:aType time:aTime]; + if (nil != self) { + _value = aValue; + } + return self; +} + +- (void)_appendDescription:(NSMutableString *)s +{ + [super _appendDescription:s]; + + if (nil != _value) { + [s appendFormat:@"; value = %@", _value]; + } + + if (nil != _velocity) { + [s appendFormat:@"; velocity = %@", _velocity]; + } +} + +@end diff --git a/Example/Pods/pop/pop/POPAnimationEventInternal.h b/Example/Pods/pop/pop/POPAnimationEventInternal.h new file mode 100644 index 0000000..398d59b --- /dev/null +++ b/Example/Pods/pop/pop/POPAnimationEventInternal.h @@ -0,0 +1,41 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#import + +#import "POPAnimationEvent.h" + +@interface POPAnimationEvent () + +/** + @abstract Default initializer. + */ +- (instancetype)initWithType:(POPAnimationEventType)type time:(CFTimeInterval)time; + +/** + @abstract Readwrite redefinition of public property. + */ +@property (readwrite, nonatomic, copy) NSString *animationDescription; + +@end + +@interface POPAnimationValueEvent () + +/** + @abstract Default initializer. + */ +- (instancetype)initWithType:(POPAnimationEventType)type time:(CFTimeInterval)time value:(id)value; + +/** + @abstract Readwrite redefinition of public property. + */ +@property (readwrite, nonatomic, strong) id velocity; + +@end + diff --git a/Example/Pods/pop/pop/POPAnimationExtras.h b/Example/Pods/pop/pop/POPAnimationExtras.h new file mode 100644 index 0000000..4b3d237 --- /dev/null +++ b/Example/Pods/pop/pop/POPAnimationExtras.h @@ -0,0 +1,43 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#import + +#import +#import + +/** + @abstract The current drag coefficient. + @discussion A value greater than 1.0 indicates Simulator slow-motion animations are enabled. Defaults to 1.0. + */ +extern CGFloat POPAnimationDragCoefficient(); + +@interface CAAnimation (POPAnimationExtras) + +/** + @abstract Apply the current drag coefficient to animation speed. + @discussion Convenience utility to respect Simulator slow-motion animation settings. + */ +- (void)pop_applyDragCoefficient; + +@end + +@interface POPSpringAnimation (POPAnimationExtras) + +/** + @abstract Converts from spring bounciness and speed to tension, friction and mass dynamics values. + */ ++ (void)convertBounciness:(CGFloat)bounciness speed:(CGFloat)speed toTension:(CGFloat *)outTension friction:(CGFloat *)outFriction mass:(CGFloat *)outMass; + +/** + @abstract Converts from dynamics tension, friction and mass to spring bounciness and speed values. + */ ++ (void)convertTension:(CGFloat)tension friction:(CGFloat)friction toBounciness:(CGFloat *)outBounciness speed:(CGFloat *)outSpeed; + +@end diff --git a/Example/Pods/pop/pop/POPAnimationExtras.mm b/Example/Pods/pop/pop/POPAnimationExtras.mm new file mode 100644 index 0000000..941aaaf --- /dev/null +++ b/Example/Pods/pop/pop/POPAnimationExtras.mm @@ -0,0 +1,117 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#import "POPAnimationExtras.h" + +#import "POPAnimationPrivate.h" +#import "POPMath.h" + +#if TARGET_OS_IPHONE +#import +#endif + +#if TARGET_IPHONE_SIMULATOR +UIKIT_EXTERN CGFloat UIAnimationDragCoefficient(); // UIKit private drag coeffient, use judiciously +#endif + +CGFloat POPAnimationDragCoefficient() +{ +#if TARGET_IPHONE_SIMULATOR + return UIAnimationDragCoefficient(); +#else + return 1.0; +#endif +} + +@implementation CAAnimation (POPAnimationExtras) + +- (void)pop_applyDragCoefficient +{ + CGFloat k = POPAnimationDragCoefficient(); + if (k != 0 && k != 1) + self.speed = 1 / k; +} + +@end + +@implementation POPSpringAnimation (POPAnimationExtras) + +static const CGFloat POPBouncy3NormalizationRange = 20.0; +static const CGFloat POPBouncy3NormalizationScale = 1.7; +static const CGFloat POPBouncy3BouncinessNormalizedMin = 0.0; +static const CGFloat POPBouncy3BouncinessNormalizedMax = 0.8; +static const CGFloat POPBouncy3SpeedNormalizedMin = 0.5; +static const CGFloat POPBouncy3SpeedNormalizedMax = 200; +static const CGFloat POPBouncy3FrictionInterpolationMax = 0.01; + ++ (void)convertBounciness:(CGFloat)bounciness speed:(CGFloat)speed toTension:(CGFloat *)outTension friction:(CGFloat *)outFriction mass:(CGFloat *)outMass +{ + double b = POPNormalize(bounciness / POPBouncy3NormalizationScale, 0, POPBouncy3NormalizationRange); + b = POPProjectNormal(b, POPBouncy3BouncinessNormalizedMin, POPBouncy3BouncinessNormalizedMax); + + double s = POPNormalize(speed / POPBouncy3NormalizationScale, 0, POPBouncy3NormalizationRange); + + CGFloat tension = POPProjectNormal(s, POPBouncy3SpeedNormalizedMin, POPBouncy3SpeedNormalizedMax); + CGFloat friction = POPQuadraticOutInterpolation(b, POPBouncy3NoBounce(tension), POPBouncy3FrictionInterpolationMax); + + tension = POP_ANIMATION_TENSION_FOR_QC_TENSION(tension); + friction = POP_ANIMATION_FRICTION_FOR_QC_FRICTION(friction); + + if (outTension) { + *outTension = tension; + } + + if (outFriction) { + *outFriction = friction; + } + + if (outMass) { + *outMass = 1.0; + } +} + ++ (void)convertTension:(CGFloat)tension friction:(CGFloat)friction toBounciness:(CGFloat *)outBounciness speed:(CGFloat *)outSpeed +{ + // Convert to QC values, in which our calculations are done. + CGFloat qcFriction = QC_FRICTION_FOR_POP_ANIMATION_FRICTION(friction); + CGFloat qcTension = QC_TENSION_FOR_POP_ANIMATION_TENSION(tension); + + // Friction is a function of bounciness and tension, according to the following: + // friction = POPQuadraticOutInterpolation(b, POPBouncy3NoBounce(tension), POPBouncy3FrictionInterpolationMax); + // Solve for bounciness, given a tension and friction. + + CGFloat nobounceTension = POPBouncy3NoBounce(qcTension); + CGFloat bounciness1, bounciness2; + + POPQuadraticSolve((nobounceTension - POPBouncy3FrictionInterpolationMax), // a + 2 * (POPBouncy3FrictionInterpolationMax - nobounceTension), // b + (nobounceTension - qcFriction), // c + bounciness1, // x1 + bounciness2); // x2 + + + // Choose the quadratic solution within the normalized bounciness range + CGFloat projectedNormalizedBounciness = (bounciness2 < POPBouncy3BouncinessNormalizedMax) ? bounciness2 : bounciness1; + CGFloat projectedNormalizedSpeed = qcTension; + + // Reverse projection + normalization + CGFloat bounciness = ((POPBouncy3NormalizationRange * POPBouncy3NormalizationScale) / (POPBouncy3BouncinessNormalizedMax - POPBouncy3BouncinessNormalizedMin)) * (projectedNormalizedBounciness - POPBouncy3BouncinessNormalizedMin); + CGFloat speed = ((POPBouncy3NormalizationRange * POPBouncy3NormalizationScale) / (POPBouncy3SpeedNormalizedMax - POPBouncy3SpeedNormalizedMin)) * (projectedNormalizedSpeed - POPBouncy3SpeedNormalizedMin); + + // Write back results + if (outBounciness) { + *outBounciness = bounciness; + } + + if (outSpeed) { + *outSpeed = speed; + } +} + +@end diff --git a/Example/Pods/pop/pop/POPAnimationInternal.h b/Example/Pods/pop/pop/POPAnimationInternal.h new file mode 100644 index 0000000..ecab1b6 --- /dev/null +++ b/Example/Pods/pop/pop/POPAnimationInternal.h @@ -0,0 +1,480 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#import + +#import "POPAnimation.h" +#import "POPAnimationRuntime.h" +#import "POPAnimationTracerInternal.h" +#import "POPSpringSolver.h" +#import "POPAction.h" + +using namespace POP; + +/** + Enumeration of supported animation types. + */ +enum POPAnimationType +{ + kPOPAnimationSpring, + kPOPAnimationDecay, + kPOPAnimationBasic, + kPOPAnimationCustom, +}; + +typedef struct +{ + CGFloat progress; + bool reached; +} POPProgressMarker; + +typedef void (^POPAnimationCompletionBlock)(POPAnimation *anim, BOOL finished); + +@interface POPAnimation() +- (instancetype)_init; + +@property (assign, nonatomic) SpringSolver4d *solver; +@property (readonly, nonatomic) POPAnimationType type; + +/** + The current animation value, updated while animation is progressing. + */ +@property (copy, nonatomic, readonly) id currentValue; + +/** + An array of optional progress markers. For each marker specified, the animation delegate will be informed when progress meets or exceeds the value specified. Specifying values outside of the [0, 1] range will give undefined results. + */ +@property (copy, nonatomic) NSArray *progressMarkers; + +/** + Return YES to indicate animation should continue animating. + */ +- (BOOL)_advance:(id)object currentTime:(CFTimeInterval)currentTime elapsedTime:(CFTimeInterval)elapsedTime; + +/** + Subclass override point to append animation description. + */ +- (void)_appendDescription:(NSMutableString *)s debug:(BOOL)debug; + +@end + +NS_INLINE NSString *describe(VectorConstRef vec) +{ + return NULL == vec ? @"null" : vec->toString(); +} + +NS_INLINE Vector4r vector4(VectorConstRef vec) +{ + return NULL == vec ? Vector4r::Zero() : vec->vector4r(); +} + +NS_INLINE Vector4d vector4d(VectorConstRef vec) +{ + if (NULL == vec) { + return Vector4d::Zero(); + } else { + return vec->vector4r().cast(); + } +} + +NS_INLINE bool vec_equal(VectorConstRef v1, VectorConstRef v2) +{ + if (v1 == v2) { + return true; + } + if (!v1 || !v2) { + return false; + } + return *v1 == *v2; +} + +NS_INLINE CGFloat * vec_data(VectorRef vec) +{ + return NULL == vec ? NULL : vec->data(); +} + +template +struct ComputeProgressFunctor { + CGFloat operator()(const T &value, const T &start, const T &end) const { + return 0; + } +}; + +template<> +struct ComputeProgressFunctor { + CGFloat operator()(const Vector4r &value, const Vector4r &start, const Vector4r &end) const { + CGFloat s = (value - start).squaredNorm(); // distance from start + CGFloat e = (value - end).squaredNorm(); // distance from end + CGFloat d = (end - start).squaredNorm(); // distance from start to end + + if (0 == d) { + return 1; + } else if (s > e) { + // s -------- p ---- e OR s ------- e ---- p + return sqrtr(s/d); + } else { + // s --- p --------- e OR p ---- s ------- e + return 1 - sqrtr(e/d); + } + } +}; + +struct _POPAnimationState; +struct _POPDecayAnimationState; +struct _POPPropertyAnimationState; + +extern _POPAnimationState *POPAnimationGetState(POPAnimation *a); + + +#define FB_FLAG_GET(stype, flag, getter) \ +- (BOOL)getter { \ + return ((stype *)_state)->flag; \ +} + +#define FB_FLAG_SET(stype, flag, mutator) \ +- (void)mutator (BOOL)value { \ + if (value == ((stype *)_state)->flag) \ + return; \ + ((stype *)_state)->flag = value; \ +} + +#define DEFINE_RW_FLAG(stype, flag, getter, mutator) \ + FB_FLAG_GET (stype, flag, getter) \ + FB_FLAG_SET (stype, flag, mutator) + +#define FB_PROPERTY_GET(stype, property, ctype) \ +- (ctype)property { \ + return ((stype *)_state)->property; \ +} + +#define FB_PROPERTY_SET(stype, property, mutator, ctype, ...) \ +- (void)mutator (ctype)value { \ + if (value == ((stype *)_state)->property) \ + return; \ + ((stype *)_state)->property = value; \ + __VA_ARGS__ \ +} + +#define FB_PROPERTY_SET_OBJ_COPY(stype, property, mutator, ctype, ...) \ +- (void)mutator (ctype)value { \ + if (value == ((stype *)_state)->property) \ + return; \ + ((stype *)_state)->property = [value copy]; \ + __VA_ARGS__ \ +} + +#define DEFINE_RW_PROPERTY(stype, flag, mutator, ctype, ...) \ + FB_PROPERTY_GET (stype, flag, ctype) \ + FB_PROPERTY_SET (stype, flag, mutator, ctype, __VA_ARGS__) + +#define DEFINE_RW_PROPERTY_OBJ(stype, flag, mutator, ctype, ...) \ + FB_PROPERTY_GET (stype, flag, ctype) \ + FB_PROPERTY_SET (stype, flag, mutator, ctype, __VA_ARGS__) + +#define DEFINE_RW_PROPERTY_OBJ_COPY(stype, flag, mutator, ctype, ...) \ + FB_PROPERTY_GET (stype, flag, ctype) \ + FB_PROPERTY_SET_OBJ_COPY (stype, flag, mutator, ctype, __VA_ARGS__) + + +/** + Internal delegate definition. + */ +@interface NSObject (POPAnimationDelegateInternal) +- (void)pop_animation:(POPAnimation *)anim didReachProgress:(CGFloat)progress; +@end + +struct _POPAnimationState +{ + id __unsafe_unretained self; + POPAnimationType type; + NSString *name; + NSUInteger ID; + CFTimeInterval beginTime; + CFTimeInterval startTime; + CFTimeInterval lastTime; + id __weak delegate; + POPAnimationCompletionBlock completionBlock; + NSMutableDictionary *dict; + POPAnimationTracer *tracer; + CGFloat progress; + NSInteger repeatCount; + + bool active:1; + bool paused:1; + bool removedOnCompletion:1; + + bool delegateDidStart:1; + bool delegateDidStop:1; + bool delegateDidProgress:1; + bool delegateDidApply:1; + bool delegateDidReachToValue:1; + + bool additive:1; + bool didReachToValue:1; + bool tracing:1; // corresponds to tracer started + bool userSpecifiedDynamics:1; + bool autoreverses:1; + bool repeatForever:1; + bool customFinished:1; + + _POPAnimationState(id __unsafe_unretained anim) : + self(anim), + type((POPAnimationType)0), + name(nil), + ID(0), + beginTime(0), + startTime(0), + lastTime(0), + delegate(nil), + completionBlock(nil), + dict(nil), + tracer(nil), + progress(0), + repeatCount(0), + active(false), + paused(true), + removedOnCompletion(true), + delegateDidStart(false), + delegateDidStop(false), + delegateDidProgress(false), + delegateDidApply(false), + delegateDidReachToValue(false), + additive(false), + didReachToValue(false), + tracing(false), + userSpecifiedDynamics(false), + autoreverses(false), + repeatForever(false), + customFinished(false) {} + + virtual ~_POPAnimationState() + { + name = nil; + dict = nil; + tracer = nil; + completionBlock = NULL; + } + + bool isCustom() { + return kPOPAnimationCustom == type; + } + + bool isStarted() { + return 0 != startTime; + } + + id getDelegate() { + return delegate; + } + + void setDelegate(id d) { + if (d != delegate) { + delegate = d; + delegateDidStart = [d respondsToSelector:@selector(pop_animationDidStart:)]; + delegateDidStop = [d respondsToSelector:@selector(pop_animationDidStop:finished:)]; + delegateDidProgress = [d respondsToSelector:@selector(pop_animation:didReachProgress:)]; + delegateDidApply = [d respondsToSelector:@selector(pop_animationDidApply:)]; + delegateDidReachToValue = [d respondsToSelector:@selector(pop_animationDidReachToValue:)]; + } + } + + bool getPaused() { + return paused; + } + + void setPaused(bool f) { + if (f != paused) { + paused = f; + if (!paused) { + reset(false); + } + } + } + + CGFloat getProgress() { + return progress; + } + + /* returns true if started */ + bool startIfNeeded(id obj, CFTimeInterval time, CFTimeInterval offset) + { + bool started = false; + + // detect start based on time + if (0 == startTime && time >= beginTime + offset) { + + // activate & unpause + active = true; + setPaused(false); + + // note start time + startTime = lastTime = time; + started = true; + } + + // ensure values for running animation + bool running = active && !paused; + if (running) { + willRun(started, obj); + } + + // handle start + if (started) { + handleDidStart(); + } + + return started; + } + + void stop(bool removing, bool done) { + if (active) + { + // delegate progress one last time + if (done) { + delegateProgress(); + } + + if (removing) { + active = false; + } + + handleDidStop(done); + } else { + + // stopped before even started + // delegate start and stop regardless; matches CA behavior + if (!isStarted()) { + handleDidStart(); + handleDidStop(false); + } + } + + setPaused(true); + } + + virtual void handleDidStart() + { + if (delegateDidStart) { + ActionEnabler enabler; + [delegate pop_animationDidStart:self]; + } + + if (tracing) { + [tracer didStart]; + } + } + + void handleDidStop(BOOL done) + { + if (delegateDidStop) { + ActionEnabler enabler; + [delegate pop_animationDidStop:self finished:done]; + } + + // add another strong reference to completion block before callout + POPAnimationCompletionBlock block = completionBlock; + if (block != NULL) { + ActionEnabler enabler; + block(self, done); + } + + if (tracing) { + [tracer didStop:done]; + } + } + + /* virtual functions */ + virtual bool isDone() { + if (isCustom()) { + return customFinished; + } + + return false; + } + + bool advanceTime(CFTimeInterval time, id obj) { + bool advanced = false; + bool computedProgress = false; + CFTimeInterval dt = time - lastTime; + + switch (type) { + case kPOPAnimationSpring: + advanced = advance(time, dt, obj); + break; + case kPOPAnimationDecay: + advanced = advance(time, dt, obj); + break; + case kPOPAnimationBasic: { + advanced = advance(time, dt, obj); + computedProgress = true; + break; + } + case kPOPAnimationCustom: { + customFinished = [self _advance:obj currentTime:time elapsedTime:dt] ? false : true; + advanced = true; + break; + } + default: + break; + } + + if (advanced) { + + // estimate progress + if (!computedProgress) { + computeProgress(); + } + + // delegate progress + delegateProgress(); + + // update time + lastTime = time; + } + + return advanced; + } + + virtual void willRun(bool started, id obj) {} + virtual bool advance(CFTimeInterval time, CFTimeInterval dt, id obj) { return false; } + virtual void computeProgress() {} + virtual void delegateProgress() {} + + virtual void delegateApply() { + if (delegateDidApply) { + ActionEnabler enabler; + [delegate pop_animationDidApply:self]; + } + } + + virtual void reset(bool all) { + startTime = 0; + lastTime = 0; + } +}; + +typedef struct _POPAnimationState POPAnimationState; + + +@interface POPAnimation () +{ +@protected + struct _POPAnimationState *_state; +} + +@end + +// NSProxy extensions, for testing pursposes +@interface NSProxy (POP) +- (void)pop_addAnimation:(POPAnimation *)anim forKey:(NSString *)key; +- (void)pop_removeAllAnimations; +- (void)pop_removeAnimationForKey:(NSString *)key; +- (NSArray *)pop_animationKeys; +- (POPAnimation *)pop_animationForKey:(NSString *)key; +@end diff --git a/Example/Pods/pop/pop/POPAnimationPrivate.h b/Example/Pods/pop/pop/POPAnimationPrivate.h new file mode 100644 index 0000000..c0f06c5 --- /dev/null +++ b/Example/Pods/pop/pop/POPAnimationPrivate.h @@ -0,0 +1,16 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#import + +#define POP_ANIMATION_FRICTION_FOR_QC_FRICTION(qcFriction) (25.0 + (((qcFriction - 8.0) / 2.0) * (25.0 - 19.0))) +#define POP_ANIMATION_TENSION_FOR_QC_TENSION(qcTension) (194.0 + (((qcTension - 30.0) / 50.0) * (375.0 - 194.0))) + +#define QC_FRICTION_FOR_POP_ANIMATION_FRICTION(fbFriction) (8.0 + 2.0 * ((fbFriction - 25.0)/(25.0 - 19.0))) +#define QC_TENSION_FOR_POP_ANIMATION_TENSION(fbTension) (30.0 + 50.0 * ((fbTension - 194.0)/(375.0 - 194.0))) diff --git a/Example/Pods/pop/pop/POPAnimationRuntime.h b/Example/Pods/pop/pop/POPAnimationRuntime.h new file mode 100644 index 0000000..788c8c6 --- /dev/null +++ b/Example/Pods/pop/pop/POPAnimationRuntime.h @@ -0,0 +1,101 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#import + +#import + +#import "POPVector.h" + +enum POPValueType +{ + kPOPValueUnknown = 0, + kPOPValueInteger, + kPOPValueFloat, + kPOPValuePoint, + kPOPValueSize, + kPOPValueRect, + kPOPValueEdgeInsets, + kPOPValueAffineTransform, + kPOPValueTransform, + kPOPValueRange, + kPOPValueColor, +}; + +using namespace POP; + +/** + Returns value type based on objc type description, given list of supported value types and length. + */ +extern POPValueType POPSelectValueType(const char *objctype, const POPValueType *types, size_t length); + +/** + Returns value type based on objc object, given a list of supported value types and length. + */ +extern POPValueType POPSelectValueType(id obj, const POPValueType *types, size_t length); + +/** + Array of all value types. + */ +extern const POPValueType kPOPAnimatableAllTypes[10]; + +/** + Array of all value types supported for animation. + */ +extern const POPValueType kPOPAnimatableSupportTypes[8]; + +/** + Returns a string description of a value type. + */ +extern NSString *POPValueTypeToString(POPValueType t); + +/** + Returns a mutable dictionary of weak pointer keys to weak pointer values. + */ +extern CFMutableDictionaryRef POPDictionaryCreateMutableWeakPointerToWeakPointer(NSUInteger capacity) CF_RETURNS_RETAINED; + +/** + Returns a mutable dictionary of weak pointer keys to weak pointer values. + */ +extern CFMutableDictionaryRef POPDictionaryCreateMutableWeakPointerToStrongObject(NSUInteger capacity) CF_RETURNS_RETAINED; + +/** + Box a vector. + */ +extern id POPBox(VectorConstRef vec, POPValueType type, bool force = false); + +/** + Unbox a vector. + */ +extern VectorRef POPUnbox(id value, POPValueType &type, NSUInteger &count, bool validate); + +/** + Read/write block typedefs for convenience. + */ +typedef void(^pop_animatable_read_block)(id obj, CGFloat *value); +typedef void(^pop_animatable_write_block)(id obj, const CGFloat *value); + +/** + Read object value and return a Vector4r. + */ +NS_INLINE Vector4r read_values(pop_animatable_read_block read, id obj, size_t count) +{ + Vector4r vec = Vector4r::Zero(); + if (0 == count) + return vec; + + read(obj, vec.data()); + + return vec; +} + +NS_INLINE NSString *POPStringFromBOOL(BOOL value) +{ + return value ? @"YES" : @"NO"; +} diff --git a/Example/Pods/pop/pop/POPAnimationRuntime.mm b/Example/Pods/pop/pop/POPAnimationRuntime.mm new file mode 100644 index 0000000..af3f301 --- /dev/null +++ b/Example/Pods/pop/pop/POPAnimationRuntime.mm @@ -0,0 +1,288 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#import "POPAnimationRuntime.h" + +#import + +#import + +#if TARGET_OS_IPHONE +#import +#endif + +#import "POPVector.h" +#import "POPAnimationRuntime.h" +#import "POPCGUtils.h" +#import "POPGeometry.h" + +static Boolean pointerEqual(const void *ptr1, const void *ptr2) { + return ptr1 == ptr2; +} + +static CFHashCode pointerHash(const void *ptr) { + return (CFHashCode)(ptr); +} + +CFMutableDictionaryRef POPDictionaryCreateMutableWeakPointerToWeakPointer(NSUInteger capacity) +{ + CFDictionaryKeyCallBacks kcb = kCFTypeDictionaryKeyCallBacks; + + // weak, pointer keys + kcb.retain = NULL; + kcb.retain = NULL; + kcb.equal = pointerEqual; + kcb.hash = pointerHash; + + CFDictionaryValueCallBacks vcb = kCFTypeDictionaryValueCallBacks; + + // weak, pointer values + vcb.retain = NULL; + vcb.release = NULL; + vcb.equal = pointerEqual; + + return CFDictionaryCreateMutable(NULL, capacity, &kcb, &vcb); +} + +CFMutableDictionaryRef POPDictionaryCreateMutableWeakPointerToStrongObject(NSUInteger capacity) +{ + CFDictionaryKeyCallBacks kcb = kCFTypeDictionaryKeyCallBacks; + + // weak, pointer keys + kcb.retain = NULL; + kcb.release = NULL; + kcb.equal = pointerEqual; + kcb.hash = pointerHash; + + // strong, object values + CFDictionaryValueCallBacks vcb = kCFTypeDictionaryValueCallBacks; + + return CFDictionaryCreateMutable(NULL, capacity, &kcb, &vcb); +} + +static bool FBCompareTypeEncoding(const char *objctype, POPValueType type) +{ + switch (type) + { + case kPOPValueFloat: + return (strcmp(objctype, @encode(float)) == 0 + || strcmp(objctype, @encode(double)) == 0 + ); + + case kPOPValuePoint: + return (strcmp(objctype, @encode(CGPoint)) == 0 +#if !TARGET_OS_IPHONE + || strcmp(objctype, @encode(NSPoint)) == 0 +#endif + ); + + case kPOPValueSize: + return (strcmp(objctype, @encode(CGSize)) == 0 +#if !TARGET_OS_IPHONE + || strcmp(objctype, @encode(NSSize)) == 0 +#endif + ); + + case kPOPValueRect: + return (strcmp(objctype, @encode(CGRect)) == 0 +#if !TARGET_OS_IPHONE + || strcmp(objctype, @encode(NSRect)) == 0 +#endif + ); + case kPOPValueEdgeInsets: +#if TARGET_OS_IPHONE + return strcmp(objctype, @encode(UIEdgeInsets)) == 0; +#else + return false; +#endif + + case kPOPValueAffineTransform: + return strcmp(objctype, @encode(CGAffineTransform)) == 0; + + case kPOPValueTransform: + return strcmp(objctype, @encode(CATransform3D)) == 0; + + case kPOPValueRange: + return strcmp(objctype, @encode(CFRange)) == 0 + || strcmp(objctype, @encode (NSRange)) == 0; + + case kPOPValueInteger: + return (strcmp(objctype, @encode(int)) == 0 + || strcmp(objctype, @encode(unsigned int)) == 0 + || strcmp(objctype, @encode(short)) == 0 + || strcmp(objctype, @encode(unsigned short)) == 0 + || strcmp(objctype, @encode(long)) == 0 + || strcmp(objctype, @encode(unsigned long)) == 0 + || strcmp(objctype, @encode(long long)) == 0 + || strcmp(objctype, @encode(unsigned long long)) == 0 + ); + default: + return false; + } +} + +POPValueType POPSelectValueType(const char *objctype, const POPValueType *types, size_t length) +{ + if (NULL != objctype) { + for (size_t idx = 0; idx < length; idx++) { + if (FBCompareTypeEncoding(objctype, types[idx])) + return types[idx]; + } + } + return kPOPValueUnknown; +} + +POPValueType POPSelectValueType(id obj, const POPValueType *types, size_t length) +{ + if ([obj isKindOfClass:[NSValue class]]) { + return POPSelectValueType([obj objCType], types, length); + } else if (NULL != POPCGColorWithColor(obj)) { + return kPOPValueColor; + } + return kPOPValueUnknown; +} + +const POPValueType kPOPAnimatableAllTypes[10] = {kPOPValueInteger, kPOPValueFloat, kPOPValuePoint, kPOPValueSize, kPOPValueRect, kPOPValueEdgeInsets, kPOPValueAffineTransform, kPOPValueTransform, kPOPValueRange, kPOPValueColor}; + +const POPValueType kPOPAnimatableSupportTypes[8] = {kPOPValueInteger, kPOPValueFloat, kPOPValuePoint, kPOPValueSize, kPOPValueRect, kPOPValueEdgeInsets, kPOPValueColor}; + +NSString *POPValueTypeToString(POPValueType t) +{ + switch (t) { + case kPOPValueUnknown: + return @"unknown"; + case kPOPValueInteger: + return @"int"; + case kPOPValueFloat: + return @"CGFloat"; + case kPOPValuePoint: + return @"CGPoint"; + case kPOPValueSize: + return @"CGSize"; + case kPOPValueRect: + return @"CGRect"; + case kPOPValueEdgeInsets: + return @"UIEdgeInsets"; + case kPOPValueAffineTransform: + return @"CGAffineTransform"; + case kPOPValueTransform: + return @"CATransform3D"; + case kPOPValueRange: + return @"CFRange"; + case kPOPValueColor: + return @"CGColorRef"; + default: + return nil; + } +} + +id POPBox(VectorConstRef vec, POPValueType type, bool force) +{ + if (NULL == vec) + return nil; + + switch (type) { + case kPOPValueInteger: + case kPOPValueFloat: + return @(vec->data()[0]); + break; + case kPOPValuePoint: + return [NSValue valueWithCGPoint:vec->cg_point()]; + break; + case kPOPValueSize: + return [NSValue valueWithCGSize:vec->cg_size()]; + break; + case kPOPValueRect: + return [NSValue valueWithCGRect:vec->cg_rect()]; + break; +#if TARGET_OS_IPHONE + case kPOPValueEdgeInsets: + return [NSValue valueWithUIEdgeInsets:vec->ui_edge_insets()]; + break; +#endif + case kPOPValueColor: { + return (__bridge_transfer id)vec->cg_color(); + break; + } + default: + return force ? [NSValue valueWithCGPoint:vec->cg_point()] : nil; + break; + } +} + +static VectorRef vectorize(id value, POPValueType type) +{ + Vector *vec = NULL; + + switch (type) { + case kPOPValueInteger: + case kPOPValueFloat: + vec = Vector::new_cg_float([value floatValue]); + break; + case kPOPValuePoint: + vec = Vector::new_cg_point([value CGPointValue]); + break; + case kPOPValueSize: + vec = Vector::new_cg_size([value CGSizeValue]); + break; + case kPOPValueRect: + vec = Vector::new_cg_rect([value CGRectValue]); + break; +#if TARGET_OS_IPHONE + case kPOPValueEdgeInsets: + vec = Vector::new_ui_edge_insets([value UIEdgeInsetsValue]); + break; +#endif + case kPOPValueAffineTransform: + vec = Vector::new_cg_affine_transform([value CGAffineTransformValue]); + break; + case kPOPValueColor: + vec = Vector::new_cg_color(POPCGColorWithColor(value)); + break; + default: + break; + } + + return VectorRef(vec); +} + +VectorRef POPUnbox(id value, POPValueType &animationType, NSUInteger &count, bool validate) +{ + if (nil == value) { + count = 0; + return VectorRef(NULL); + } + + // determine type of value + POPValueType valueType = POPSelectValueType(value, kPOPAnimatableSupportTypes, POP_ARRAY_COUNT(kPOPAnimatableSupportTypes)); + + // handle unknown types + if (kPOPValueUnknown == valueType) { + NSString *valueDesc = kPOPValueUnknown != valueType ? POPValueTypeToString(valueType) : [[value class] description]; + [NSException raise:@"Unsuported value" format:@"Animating %@ values is not supported", valueDesc]; + } + + // vectorize + VectorRef vec = vectorize(value, valueType); + + if (kPOPValueUnknown == animationType || 0 == count) { + // update animation type based on value type + animationType = valueType; + if (NULL != vec) { + count = vec->size(); + } + } else if (validate) { + // allow for mismatched types, so long as vector size matches + if (count != vec->size()) { + [NSException raise:@"Invalid value" format:@"%@ should be of type %@", value, POPValueTypeToString(animationType)]; + } + } + + return vec; +} diff --git a/Example/Pods/pop/pop/POPAnimationTracer.h b/Example/Pods/pop/pop/POPAnimationTracer.h new file mode 100644 index 0000000..72b26c3 --- /dev/null +++ b/Example/Pods/pop/pop/POPAnimationTracer.h @@ -0,0 +1,60 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#import + +#import + +@class POPAnimation; + +/** + @abstract Tracer of animation events to fasciliate unit testing & debugging. + */ +@interface POPAnimationTracer : NSObject + +/** + @abstract Start recording events. + */ +- (void)start; + +/** + @abstract Stop recording events. + */ +- (void)stop; + +/** + @abstract Resets any recoded events. Continues recording events if already started. + */ +- (void)reset; + +/** + @abstract Property representing all recorded events. + @discussion Events are returned in order of occurence. + */ +@property (nonatomic, assign, readonly) NSArray *allEvents; + +/** + @abstract Property representing all recorded write events for convenience. + @discussion Events are returned in order of occurence. + */ +@property (nonatomic, assign, readonly) NSArray *writeEvents; + +/** + @abstract Queries for events of specified type. + @param type The type of event to return. + @returns An array of events of specified type in order of occurence. + */ +- (NSArray *)eventsWithType:(POPAnimationEventType)type; + +/** + @abstract Property indicating whether tracer should automatically log events and reset collection on animation completion. + */ +@property (nonatomic, assign) BOOL shouldLogAndResetOnCompletion; + +@end diff --git a/Example/Pods/pop/pop/POPAnimationTracer.mm b/Example/Pods/pop/pop/POPAnimationTracer.mm new file mode 100644 index 0000000..243fb9b --- /dev/null +++ b/Example/Pods/pop/pop/POPAnimationTracer.mm @@ -0,0 +1,191 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#import "POPAnimationTracer.h" + +#import + +#import "POPAnimationEventInternal.h" +#import "POPAnimationInternal.h" +#import "POPSpringAnimation.h" + +@implementation POPAnimationTracer +{ + __weak POPAnimation *_animation; + POPAnimationState *_animationState; + NSMutableArray *_events; + BOOL _animationHasVelocity; +} +@synthesize shouldLogAndResetOnCompletion = _shouldLogAndResetOnCompletion; + +static POPAnimationEvent *create_event(POPAnimationTracer *self, POPAnimationEventType type, id value = nil, bool recordAnimation = false) +{ + bool useLocalTime = 0 != self->_animationState->startTime; + CFTimeInterval time = useLocalTime + ? self->_animationState->lastTime - self->_animationState->startTime + : self->_animationState->lastTime; + + POPAnimationEvent *event; + + if (!value) { + event = [[POPAnimationEvent alloc] initWithType:type time:time]; + } else { + event = [[POPAnimationValueEvent alloc] initWithType:type time:time value:value]; + if (self->_animationHasVelocity) { + [(POPAnimationValueEvent *)event setVelocity:[(POPSpringAnimation *)self->_animation velocity]]; + } + } + + if (recordAnimation) { + event.animationDescription = [self->_animation description]; + } + + return event; +} + +- (id)initWithAnimation:(POPAnimation *)anAnim +{ + self = [super init]; + if (nil != self) { + _animation = anAnim; + _animationState = POPAnimationGetState(anAnim); + _events = [[NSMutableArray alloc] initWithCapacity:50]; + _animationHasVelocity = [anAnim respondsToSelector:@selector(velocity)]; + } + return self; +} + +- (void)readPropertyValue:(id)aValue +{ + POPAnimationEvent *event = create_event(self, kPOPAnimationEventPropertyRead, aValue); + [_events addObject:event]; +} + +- (void)writePropertyValue:(id)aValue +{ + POPAnimationEvent *event = create_event(self, kPOPAnimationEventPropertyWrite, aValue); + [_events addObject:event]; +} + +- (void)updateToValue:(id)aValue +{ + POPAnimationEvent *event = create_event(self, kPOPAnimationEventToValueUpdate, aValue); + [_events addObject:event]; +} + +- (void)updateFromValue:(id)aValue +{ + POPAnimationEvent *event = create_event(self, kPOPAnimationEventFromValueUpdate, aValue); + [_events addObject:event]; +} + +- (void)updateVelocity:(id)aValue +{ + POPAnimationEvent *event = create_event(self, kPOPAnimationEventVelocityUpdate, aValue); + [_events addObject:event]; +} + +- (void)updateSpeed:(float)aFloat +{ + POPAnimationEvent *event = create_event(self, kPOPAnimationEventSpeedUpdate, @(aFloat)); + [_events addObject:event]; +} + +- (void)updateBounciness:(float)aFloat +{ + POPAnimationEvent *event = create_event(self, kPOPAnimationEventBouncinessUpdate, @(aFloat)); + [_events addObject:event]; +} + +- (void)updateFriction:(float)aFloat +{ + POPAnimationEvent *event = create_event(self, kPOPAnimationEventFrictionUpdate, @(aFloat)); + [_events addObject:event]; +} + +- (void)updateMass:(float)aFloat +{ + POPAnimationEvent *event = create_event(self, kPOPAnimationEventMassUpdate, @(aFloat)); + [_events addObject:event]; +} + +- (void)updateTension:(float)aFloat +{ + POPAnimationEvent *event = create_event(self, kPOPAnimationEventTensionUpdate, @(aFloat)); + [_events addObject:event]; +} + +- (void)didStart +{ + POPAnimationEvent *event = create_event(self, kPOPAnimationEventDidStart, nil, true); + [_events addObject:event]; +} + +- (void)didStop:(BOOL)finished +{ + POPAnimationEvent *event = create_event(self, kPOPAnimationEventDidStop, @(finished), true); + [_events addObject:event]; + + if (_shouldLogAndResetOnCompletion) { + NSLog(@"events:%@", self.allEvents); + [self reset]; + } +} + +- (void)didReachToValue:(id)aValue +{ + POPAnimationEvent *event = create_event(self, kPOPAnimationEventDidReachToValue, aValue); + [_events addObject:event]; +} + +- (void)autoreversed +{ + POPAnimationEvent *event = create_event(self, kPOPAnimationEventAutoreversed); + [_events addObject:event]; +} + +- (void)start +{ + POPAnimationState *s = POPAnimationGetState(_animation); + s->tracing = true; +} + +- (void)stop +{ + POPAnimationState *s = POPAnimationGetState(_animation); + s->tracing = false; +} + +- (void)reset +{ + [_events removeAllObjects]; +} + +- (NSArray *)allEvents +{ + return [_events copy]; +} + +- (NSArray *)writeEvents +{ + return [self eventsWithType:kPOPAnimationEventPropertyWrite]; +} + +- (NSArray *)eventsWithType:(POPAnimationEventType)aType +{ + NSMutableArray *array = [NSMutableArray array]; + for (POPAnimationEvent *event in _events) { + if (aType == event.type) { + [array addObject:event]; + } + } + return array; +} + +@end diff --git a/Example/Pods/pop/pop/POPAnimationTracerInternal.h b/Example/Pods/pop/pop/POPAnimationTracerInternal.h new file mode 100644 index 0000000..00958e1 --- /dev/null +++ b/Example/Pods/pop/pop/POPAnimationTracerInternal.h @@ -0,0 +1,96 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#import + +#import + +@interface POPAnimationTracer (Internal) + +/** + @abstract Designated initalizer. Pass the animation being traced. + */ +- (instancetype)initWithAnimation:(POPAnimation *)anAnim; + +/** + @abstract Records read value. + */ +- (void)readPropertyValue:(id)aValue; + +/** + @abstract Records write value. + */ +- (void)writePropertyValue:(id)aValue; + +/** + Records to value update. + */ +- (void)updateToValue:(id)aValue; + +/** + @abstract Records from value update. + */ +- (void)updateFromValue:(id)aValue; + +/** + @abstract Records from value update. + */ +- (void)updateVelocity:(id)aValue; + +/** + @abstract Records bounciness update. + */ +- (void)updateBounciness:(float)aFloat; + +/** + @abstract Records speed update. + */ +- (void)updateSpeed:(float)aFloat; + +/** + @abstract Records friction update. + */ +- (void)updateFriction:(float)aFloat; + +/** + @abstract Records mass update. + */ +- (void)updateMass:(float)aFloat; + +/** + @abstract Records tension update. + */ +- (void)updateTension:(float)aFloat; + +/** + @abstract Records did add. + */ +- (void)didAdd; + +/** + @abstract Records did start. + */ +- (void)didStart; + +/** + @abstract Records did stop. + */ +- (void)didStop:(BOOL)finished; + +/** + @abstract Records did reach to value. + */ +- (void)didReachToValue:(id)aValue; + +/** + @abstract Records when an autoreverse animation takes place. + */ +- (void)autoreversed; + +@end diff --git a/Example/Pods/pop/pop/POPAnimator.h b/Example/Pods/pop/pop/POPAnimator.h new file mode 100644 index 0000000..7d71d24 --- /dev/null +++ b/Example/Pods/pop/pop/POPAnimator.h @@ -0,0 +1,47 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#import + +@protocol POPAnimatorDelegate; + +/** + @abstract The animator class renders animations. + */ +@interface POPAnimator : NSObject + +/** + @abstract The shared animator instance. + @discussion Consumers should generally use the shared instance in lieu of creating new instances. + */ ++ (instancetype)sharedAnimator; + +/** + @abstract The optional animator delegate. + */ +@property (weak, nonatomic) id delegate; + +@end + +/** + @abstract The animator delegate. + */ +@protocol POPAnimatorDelegate + +/** + @abstract Called on each frame before animation application. + */ +- (void)animatorWillAnimate:(POPAnimator *)animator; + +/** + @abstract Called on each frame after animation application. + */ +- (void)animatorDidAnimate:(POPAnimator *)animator; + +@end diff --git a/Example/Pods/pop/pop/POPAnimator.mm b/Example/Pods/pop/pop/POPAnimator.mm new file mode 100644 index 0000000..2addfba --- /dev/null +++ b/Example/Pods/pop/pop/POPAnimator.mm @@ -0,0 +1,794 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#import "POPAnimator.h" +#import "POPAnimatorPrivate.h" + +#import +#import +#import + +#import + +#import "POPAnimation.h" +#import "POPAnimationExtras.h" +#import "POPBasicAnimationInternal.h" +#import "POPDecayAnimation.h" + +using namespace std; +using namespace POP; + +#define ENABLE_LOGGING_DEBUG 0 +#define ENABLE_LOGGING_INFO 0 + +#if ENABLE_LOGGING_DEBUG +#define FBLogAnimDebug NSLog +#else +#define FBLogAnimDebug(...) +#endif + +#if ENABLE_LOGGING_INFO +#define FBLogAnimInfo NSLog +#else +#define FBLogAnimInfo(...) +#endif + +class POPAnimatorItem +{ +public: + id __weak object; + NSString *key; + POPAnimation *animation; + NSInteger refCount; + id __unsafe_unretained unretainedObject; + + POPAnimatorItem(id o, NSString *k, POPAnimation *a) POP_NOTHROW + { + object = o; + key = [k copy]; + animation = a; + refCount = 1; + unretainedObject = o; + } + + ~POPAnimatorItem() + { + } + + bool operator==(const POPAnimatorItem& o) const { + return unretainedObject == o.unretainedObject && animation == o.animation && [key isEqualToString:o.key]; + } + +}; + +typedef std::shared_ptr POPAnimatorItemRef; +typedef std::shared_ptr POPAnimatorItemConstRef; + +typedef std::list POPAnimatorItemList; +typedef POPAnimatorItemList::iterator POPAnimatorItemListIterator; +typedef POPAnimatorItemList::const_iterator POPAnimatorItemListConstIterator; + +static BOOL _disableBackgroundThread = YES; + +@interface POPAnimator () +{ +#if TARGET_OS_IPHONE + CADisplayLink *_displayLink; +#else + CVDisplayLinkRef _displayLink; +#endif + POPAnimatorItemList _list; + CFMutableDictionaryRef _dict; + NSMutableArray *_observers; + POPAnimatorItemList _pendingList; + CFRunLoopObserverRef _pendingListObserver; + CFTimeInterval _slowMotionStartTime; + CFTimeInterval _slowMotionLastTime; + CFTimeInterval _slowMotionAccumulator; + CFTimeInterval _beginTime; + OSSpinLock _lock; + BOOL _disableDisplayLink; +} +@end + +@implementation POPAnimator +@synthesize delegate = _delegate; +@synthesize disableDisplayLink = _disableDisplayLink; +@synthesize beginTime = _beginTime; + +#if !TARGET_OS_IPHONE +static CVReturn displayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp *now, const CVTimeStamp *outputTime, CVOptionFlags flagsIn, CVOptionFlags *flagsOut, void *context) +{ + if (_disableBackgroundThread) { + dispatch_async(dispatch_get_main_queue(), ^{ + [(__bridge POPAnimator*)context render]; + }); + } else { + [(__bridge POPAnimator*)context render]; + } + return kCVReturnSuccess; +} +#endif + +// call while holding lock +static void updateDisplayLink(POPAnimator *self) +{ + BOOL paused = (0 == self->_observers.count && self->_list.empty()) || self->_disableDisplayLink; + +#if TARGET_OS_IPHONE + if (paused != self->_displayLink.paused) { + FBLogAnimInfo(paused ? @"pausing display link" : @"unpausing display link"); + self->_displayLink.paused = paused; + } +#else + if (paused == CVDisplayLinkIsRunning(self->_displayLink)) { + FBLogAnimInfo(paused ? @"pausing display link" : @"unpausing display link"); + if (paused) { + CVDisplayLinkStop(self->_displayLink); + } else { + CVDisplayLinkStart(self->_displayLink); + } + } +#endif +} + +static void updateAnimatable(id obj, POPPropertyAnimationState *anim, bool shouldAvoidExtraneousWrite = false) +{ + // handle user-initiated stop or pause; hault animation + if (!anim->active || anim->paused) + return; + + if (anim->hasValue()) { + pop_animatable_write_block write = anim->property.writeBlock; + if (NULL == write) + return; + + // current animation value + VectorRef currentVec = anim->currentValue(); + + if (!anim->additive) { + + // if avoiding extraneous writes and we have a read block defined + if (shouldAvoidExtraneousWrite) { + + pop_animatable_read_block read = anim->property.readBlock; + if (read) { + // compare current animation value with object value + Vector4r currentValue = currentVec->vector4r(); + Vector4r objectValue = read_values(read, obj, anim->valueCount); + if (objectValue == currentValue) { + return; + } + } + } + + // update previous values; support animation convergence + anim->previous2Vec = anim->previousVec; + anim->previousVec = currentVec; + + // write value + write(obj, currentVec->data()); + if (anim->tracing) { + [anim->tracer writePropertyValue:POPBox(currentVec, anim->valueType, true)]; + } + } else { + pop_animatable_read_block read = anim->property.readBlock; + NSCAssert(read, @"additive requires an animatable property readBlock"); + if (NULL == read) { + return; + } + + // object value + Vector4r objectValue = read_values(read, obj, anim->valueCount); + + // current value + Vector4r currentValue = currentVec->vector4r(); + + // determine animation change + if (anim->previousVec) { + Vector4r previousValue = anim->previousVec->vector4r(); + currentValue -= previousValue; + } + + // avoid writing no change + if (shouldAvoidExtraneousWrite && currentValue == Vector4r::Zero()) { + return; + } + + // add to object value + currentValue += objectValue; + + // update previous values; support animation convergence + anim->previous2Vec = anim->previousVec; + anim->previousVec = currentVec; + + // write value + write(obj, currentValue.data()); + if (anim->tracing) { + [anim->tracer writePropertyValue:POPBox(currentVec, anim->valueType, true)]; + } + } + } +} + +static void applyAnimationTime(id obj, POPAnimationState *state, CFTimeInterval time) +{ + if (!state->advanceTime(time, obj)) { + return; + } + + POPPropertyAnimationState *ps = dynamic_cast(state); + if (NULL != ps) { + updateAnimatable(obj, ps); + } + + state->delegateApply(); +} + +static void applyAnimationToValue(id obj, POPAnimationState *state) +{ + POPPropertyAnimationState *ps = dynamic_cast(state); + + if (NULL != ps) { + + // finalize progress + ps->finalizeProgress(); + + // write to value, updating only if needed + updateAnimatable(obj, ps, true); + } + + state->delegateApply(); +} + +static POPAnimation *deleteDictEntry(POPAnimator *self, id __unsafe_unretained obj, NSString *key, BOOL cleanup = YES) +{ + POPAnimation *anim = nil; + + // lock + OSSpinLockLock(&self->_lock); + + NSMutableDictionary *keyAnimationsDict = (__bridge id)CFDictionaryGetValue(self->_dict, (__bridge void *)obj); + if (keyAnimationsDict) { + + anim = keyAnimationsDict[key]; + if (anim) { + + // remove key + [keyAnimationsDict removeObjectForKey:key]; + + // cleanup empty dictionaries + if (cleanup && 0 == keyAnimationsDict.count) { + CFDictionaryRemoveValue(self->_dict, (__bridge void *)obj); + } + } + } + + // unlock + OSSpinLockUnlock(&self->_lock); + return anim; +} + +static void stopAndCleanup(POPAnimator *self, POPAnimatorItemRef item, bool shouldRemove, bool finished) +{ + // remove + if (shouldRemove) { + deleteDictEntry(self, item->unretainedObject, item->key); + } + + // stop + POPAnimationState *state = POPAnimationGetState(item->animation); + state->stop(shouldRemove, finished); + + if (shouldRemove) { + // lock + OSSpinLockLock(&self->_lock); + + // find item in list + // may have already been removed on animationDidStop: + POPAnimatorItemListIterator find_iter = find(self->_list.begin(), self->_list.end(), item); + BOOL found = find_iter != self->_list.end(); + + if (found) { + self->_list.erase(find_iter); + } + + // unlock + OSSpinLockUnlock(&self->_lock); + } +} + ++ (id)sharedAnimator +{ + static POPAnimator* _animator = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + _animator = [[POPAnimator alloc] init]; + }); + return _animator; +} + ++ (BOOL)disableBackgroundThread +{ + return _disableBackgroundThread; +} + ++ (void)setDisableBackgroundThread:(BOOL)flag +{ + _disableBackgroundThread = flag; +} + +#pragma mark - Lifecycle + +- (id)init +{ + self = [super init]; + if (nil == self) return nil; + +#if TARGET_OS_IPHONE + _displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(render)]; + _displayLink.paused = YES; + [_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes]; +#else + CVDisplayLinkCreateWithActiveCGDisplays(&_displayLink); + CVDisplayLinkSetOutputCallback(_displayLink, displayLinkCallback, (__bridge void *)self); +#endif + + _dict = POPDictionaryCreateMutableWeakPointerToStrongObject(5); + _lock = OS_SPINLOCK_INIT; + + return self; +} + +- (void)dealloc +{ +#if TARGET_OS_IPHONE + [_displayLink invalidate]; +#else + CVDisplayLinkStop(_displayLink); + CVDisplayLinkRelease(_displayLink); +#endif + [self _clearPendingListObserver]; +} + +#pragma mark - Utility + +- (void)_processPendingList +{ + // rendering pending animations + CFTimeInterval time = [self _currentRenderTime]; + [self _renderTime:(0 != _beginTime) ? _beginTime : time items:_pendingList]; + + // lock + OSSpinLockLock(&_lock); + + // clear list and observer + _pendingList.clear(); + [self _clearPendingListObserver]; + + // unlock + OSSpinLockUnlock(&_lock); +} + +- (void)_clearPendingListObserver +{ + if (_pendingListObserver) { + CFRunLoopRemoveObserver(CFRunLoopGetMain(), _pendingListObserver, kCFRunLoopCommonModes); + CFRelease(_pendingListObserver); + _pendingListObserver = NULL; + } +} + +- (void)_scheduleProcessPendingList +{ + // see WebKit for magic numbers, eg http://trac.webkit.org/changeset/166540 + static const CFIndex CATransactionCommitRunLoopOrder = 2000000; + static const CFIndex POPAnimationApplyRunLoopOrder = CATransactionCommitRunLoopOrder - 1; + + // lock + OSSpinLockLock(&_lock); + + if (!_pendingListObserver) { + __weak POPAnimator *weakSelf = self; + + _pendingListObserver = CFRunLoopObserverCreateWithHandler(kCFAllocatorDefault, kCFRunLoopBeforeWaiting | kCFRunLoopExit, false, POPAnimationApplyRunLoopOrder, ^(CFRunLoopObserverRef observer, CFRunLoopActivity activity) { + [weakSelf _processPendingList]; + }); + + if (_pendingListObserver) { + CFRunLoopAddObserver(CFRunLoopGetMain(), _pendingListObserver, kCFRunLoopCommonModes); + } + } + + // unlock + OSSpinLockUnlock(&_lock); +} + +- (void)_renderTime:(CFTimeInterval)time items:(std::list)items +{ + // begin transaction with actions disabled + [CATransaction begin]; + [CATransaction setDisableActions:YES]; + + // notify delegate + __strong __typeof__(_delegate) delegate = _delegate; + [delegate animatorWillAnimate:self]; + + // lock + OSSpinLockLock(&_lock); + + // count active animations + const NSUInteger count = items.size(); + if (0 == count) { + // unlock + OSSpinLockUnlock(&_lock); + } else { + // copy list into vectory + std::vector vector{ std::begin(items), std::end(items) }; + + // unlock + OSSpinLockUnlock(&_lock); + + for (auto item : vector) { + [self _renderTime:time item:item]; + } + } + + // notify observers + for (id observer in self.observers) { + [observer animatorDidAnimate:(id)self]; + } + + // lock + OSSpinLockLock(&_lock); + + // update display link + updateDisplayLink(self); + + // unlock + OSSpinLockUnlock(&_lock); + + // notify delegate and commit + [delegate animatorDidAnimate:self]; + [CATransaction commit]; +} + +- (void)_renderTime:(CFTimeInterval)time item:(POPAnimatorItemRef)item +{ + id obj = item->object; + POPAnimation *anim = item->animation; + POPAnimationState *state = POPAnimationGetState(anim); + + if (nil == obj) { + // object exists not; stop animating + NSAssert(item->unretainedObject, @"object should exist"); + stopAndCleanup(self, item, true, false); + } else { + + // start if needed + state->startIfNeeded(obj, time, _slowMotionAccumulator); + + // only run active, not paused animations + if (state->active && !state->paused) { + // object exists; animate + applyAnimationTime(obj, state, time); + + FBLogAnimDebug(@"time:%f running:%@", time, item->animation); + if (state->isDone()) { + // set end value + applyAnimationToValue(obj, state); + + state->repeatCount--; + if (state->repeatForever || state->repeatCount > 0) { + if ([anim isKindOfClass:[POPPropertyAnimation class]]) { + POPPropertyAnimation *propAnim = (POPPropertyAnimation *)anim; + id oldFromValue = propAnim.fromValue; + propAnim.fromValue = propAnim.toValue; + + if (state->autoreverses) { + if (state->tracing) { + [state->tracer autoreversed]; + } + + if (state->type == kPOPAnimationDecay) { + POPDecayAnimation *decayAnimation = (POPDecayAnimation *)propAnim; + decayAnimation.velocity = [decayAnimation reversedVelocity]; + } else { + propAnim.toValue = oldFromValue; + } + } else { + if (state->type == kPOPAnimationDecay) { + POPDecayAnimation *decayAnimation = (POPDecayAnimation *)propAnim; + id originalVelocity = decayAnimation.originalVelocity; + decayAnimation.velocity = originalVelocity; + } else { + propAnim.fromValue = oldFromValue; + } + } + } + + state->stop(NO, NO); + state->reset(true); + + state->startIfNeeded(obj, time, _slowMotionAccumulator); + } else { + stopAndCleanup(self, item, state->removedOnCompletion, YES); + } + } + } + } +} + +#pragma mark - API + +- (NSArray *)observers +{ + // lock + OSSpinLockLock(&_lock); + + // get observers + NSArray *observers = 0 != _observers.count ? [_observers copy] : nil; + + // unlock + OSSpinLockUnlock(&_lock); + return observers; +} + +- (void)addAnimation:(POPAnimation *)anim forObject:(id)obj key:(NSString *)key +{ + if (!anim || !obj) { + return; + } + + // support arbitrarily many nil keys + if (!key) { + key = [[NSUUID UUID] UUIDString]; + } + + // lock + OSSpinLockLock(&_lock); + + // get key, animation dict associated with object + NSMutableDictionary *keyAnimationDict = (__bridge id)CFDictionaryGetValue(_dict, (__bridge void *)obj); + + // update associated animation state + if (nil == keyAnimationDict) { + keyAnimationDict = [NSMutableDictionary dictionary]; + CFDictionarySetValue(_dict, (__bridge void *)obj, (__bridge void *)keyAnimationDict); + } else { + // if the animation instance already exists, avoid cancelling only to restart + POPAnimation *existingAnim = keyAnimationDict[key]; + if (existingAnim) { + // unlock + OSSpinLockUnlock(&_lock); + + if (existingAnim == anim) { + return; + } + [self removeAnimationForObject:obj key:key cleanupDict:NO]; + + // lock + OSSpinLockLock(&_lock); + } + } + keyAnimationDict[key] = anim; + + // create entry after potential removal + POPAnimatorItemRef item(new POPAnimatorItem(obj, key, anim)); + + // add to list and pending list + _list.push_back(item); + _pendingList.push_back(item); + + // support animation re-use, reset all animation state + POPAnimationGetState(anim)->reset(true); + + // update display link + updateDisplayLink(self); + + // unlock + OSSpinLockUnlock(&_lock); + + // schedule runloop processing of pending animations + [self _scheduleProcessPendingList]; +} + +- (void)removeAllAnimationsForObject:(id)obj +{ + // lock + OSSpinLockLock(&_lock); + + NSArray *animations = [(__bridge id)CFDictionaryGetValue(_dict, (__bridge void *)obj) allValues]; + CFDictionaryRemoveValue(_dict, (__bridge void *)obj); + + // unlock + OSSpinLockUnlock(&_lock); + + if (0 == animations.count) { + return; + } + + NSHashTable *animationSet = [[NSHashTable alloc] initWithOptions:NSHashTableObjectPointerPersonality capacity:animations.count]; + for (id animation in animations) { + [animationSet addObject:animation]; + } + + // lock + OSSpinLockLock(&_lock); + + POPAnimatorItemRef item; + for (auto iter = _list.begin(); iter != _list.end();) { + item = *iter; + if(![animationSet containsObject:item->animation]) { + iter++; + } else { + iter = _list.erase(iter); + } + } + + // unlock + OSSpinLockUnlock(&_lock); + + for (POPAnimation *anim in animations) { + POPAnimationState *state = POPAnimationGetState(anim); + state->stop(true, !state->active); + } +} + +- (void)removeAnimationForObject:(id)obj key:(NSString *)key cleanupDict:(BOOL)cleanupDict +{ + POPAnimation *anim = deleteDictEntry(self, obj, key, cleanupDict); + if (nil == anim) { + return; + } + + // lock + OSSpinLockLock(&_lock); + + // remove from list + POPAnimatorItemRef item; + for (auto iter = _list.begin(); iter != _list.end();) { + item = *iter; + if(anim == item->animation) { + _list.erase(iter); + break; + } else { + iter++; + } + } + + // remove from pending list + for (auto iter = _pendingList.begin(); iter != _pendingList.end();) { + item = *iter; + if(anim == item->animation) { + _pendingList.erase(iter); + break; + } else { + iter++; + } + } + + // unlock + OSSpinLockUnlock(&_lock); + + // stop animation and callout + POPAnimationState *state = POPAnimationGetState(anim); + state->stop(true, (!state->active && !state->paused)); +} + +- (void)removeAnimationForObject:(id)obj key:(NSString *)key +{ + [self removeAnimationForObject:obj key:key cleanupDict:YES]; +} + +- (NSArray *)animationKeysForObject:(id)obj +{ + // lock + OSSpinLockLock(&_lock); + + // get keys + NSArray *keys = [(__bridge id)CFDictionaryGetValue(_dict, (__bridge void *)obj) allKeys]; + + // unlock + OSSpinLockUnlock(&_lock); + return keys; +} + +- (id)animationForObject:(id)obj key:(NSString *)key +{ + // lock + OSSpinLockLock(&_lock); + + // lookup animation + NSDictionary *keyAnimationsDict = (__bridge id)CFDictionaryGetValue(_dict, (__bridge void *)obj); + POPAnimation *animation = keyAnimationsDict[key]; + + // unlock + OSSpinLockUnlock(&_lock); + return animation; +} + +- (CFTimeInterval)_currentRenderTime +{ + CFTimeInterval time = CACurrentMediaTime(); + +#if TARGET_IPHONE_SIMULATOR + // support slow-motion animations + time += _slowMotionAccumulator; + float f = POPAnimationDragCoefficient(); + + if (f > 1.0) { + if (!_slowMotionStartTime) { + _slowMotionStartTime = time; + } else { + time = (time - _slowMotionStartTime) / f + _slowMotionStartTime; + _slowMotionLastTime = time; + } + } else if (_slowMotionStartTime) { + CFTimeInterval dt = (_slowMotionLastTime - time); + time += dt; + _slowMotionAccumulator += dt; + _slowMotionStartTime = 0; + } +#endif + + return time; +} + +- (void)render +{ + CFTimeInterval time = [self _currentRenderTime]; + [self renderTime:time]; +} + +- (void)renderTime:(CFTimeInterval)time +{ + [self _renderTime:time items:_list]; +} + +- (void)addObserver:(id)observer +{ + NSAssert(nil != observer, @"attempting to add nil %@ observer", self); + if (nil == observer) { + return; + } + + // lock + OSSpinLockLock(&_lock); + + if (!_observers) { + // use ordered collection for deterministic callout + _observers = [[NSMutableArray alloc] initWithCapacity:1]; + } + + [_observers addObject:observer]; + updateDisplayLink(self); + + // unlock + OSSpinLockUnlock(&_lock); +} + +- (void)removeObserver:(id)observer +{ + NSAssert(nil != observer, @"attempting to remove nil %@ observer", self); + if (nil == observer) { + return; + } + + // lock + OSSpinLockLock(&_lock); + + [_observers removeObject:observer]; + updateDisplayLink(self); + + // unlock + OSSpinLockUnlock(&_lock); +} + +@end diff --git a/Example/Pods/pop/pop/POPAnimatorPrivate.h b/Example/Pods/pop/pop/POPAnimatorPrivate.h new file mode 100644 index 0000000..5fba912 --- /dev/null +++ b/Example/Pods/pop/pop/POPAnimatorPrivate.h @@ -0,0 +1,68 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#import + +@class POPAnimation; + +@protocol POPAnimatorObserving +@required + +/** + @abstract Called on each observer after animator has advanced. Core Animation actions are disabled by default. + */ +- (void)animatorDidAnimate:(POPAnimator *)animator; + +@end + +@interface POPAnimator () + +#if !TARGET_OS_IPHONE +/** + Determines whether or not to use a high priority background thread for animation updates. Using a background thread can result in faster, more responsive updates, but may be less compatible. Defaults to YES. + */ ++ (BOOL)disableBackgroundThread; ++ (void)setDisableBackgroundThread:(BOOL)flag; +#endif + +/** + Used for externally driven animator instances. + */ +@property (assign, nonatomic) BOOL disableDisplayLink; + +/** + Time used when starting animations. Defaults to 0 meaning current media time is used. Exposed for unit testing. + */ +@property (assign, nonatomic) CFTimeInterval beginTime; + +/** + Exposed for unit testing. + */ +- (void)renderTime:(CFTimeInterval)time; + +/** + Funnel methods for category additions. + */ +- (void)addAnimation:(POPAnimation *)anim forObject:(id)obj key:(NSString *)key; +- (void)removeAllAnimationsForObject:(id)obj; +- (void)removeAnimationForObject:(id)obj key:(NSString *)key; +- (NSArray *)animationKeysForObject:(id)obj; +- (POPAnimation *)animationForObject:(id)obj key:(NSString *)key; + +/** + @abstract Add an animator observer. Observer will be notified of each subsequent animator advance until removal. + */ +- (void)addObserver:(id)observer; + +/** + @abstract Remove an animator observer. + */ +- (void)removeObserver:(id)observer; + +@end diff --git a/Example/Pods/pop/pop/POPBasicAnimation.h b/Example/Pods/pop/pop/POPBasicAnimation.h new file mode 100644 index 0000000..ce2e23a --- /dev/null +++ b/Example/Pods/pop/pop/POPBasicAnimation.h @@ -0,0 +1,71 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#import + +/** + @abstract A concrete basic animation class. + @discussion Animation is achieved through interpolation. + */ +@interface POPBasicAnimation : POPPropertyAnimation + +/** + @abstract The designated initializer. + @returns An instance of a basic animation. + */ ++ (instancetype)animation; + +/** + @abstract Convenience initializer that returns an animation with animatable property of name. + @param name The name of the animatable property. + @returns An instance of a basic animation configured with specified animatable property. + */ ++ (instancetype)animationWithPropertyNamed:(NSString *)name; + +/** + @abstract Convenience constructor. + @returns Returns a basic animation with kCAMediaTimingFunctionDefault timing function. + */ ++ (instancetype)defaultAnimation; + +/** + @abstract Convenience constructor. + @returns Returns a basic animation with kCAMediaTimingFunctionLinear timing function. + */ ++ (instancetype)linearAnimation; + +/** + @abstract Convenience constructor. + @returns Returns a basic animation with kCAMediaTimingFunctionEaseIn timing function. + */ ++ (instancetype)easeInAnimation; + +/** + @abstract Convenience constructor. + @returns Returns a basic animation with kCAMediaTimingFunctionEaseOut timing function. + */ ++ (instancetype)easeOutAnimation; + +/** + @abstract Convenience constructor. + @returns Returns a basic animation with kCAMediaTimingFunctionEaseInEaseOut timing function. + */ ++ (instancetype)easeInEaseOutAnimation; + +/** + @abstract The duration in seconds. Defaults to 0.4. + */ +@property (assign, nonatomic) CFTimeInterval duration; + +/** + @abstract A timing function defining the pacing of the animation. Defaults to nil indicating pacing according to kCAMediaTimingFunctionDefault. + */ +@property (strong, nonatomic) CAMediaTimingFunction *timingFunction; + +@end diff --git a/Example/Pods/pop/pop/POPBasicAnimation.mm b/Example/Pods/pop/pop/POPBasicAnimation.mm new file mode 100644 index 0000000..f53bba1 --- /dev/null +++ b/Example/Pods/pop/pop/POPBasicAnimation.mm @@ -0,0 +1,90 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#import "POPBasicAnimationInternal.h" + +@implementation POPBasicAnimation + +#undef __state +#define __state ((POPBasicAnimationState *)_state) + +#pragma mark - Lifecycle + ++ (instancetype)animation +{ + return [[self alloc] init]; +} + ++ (instancetype)animationWithPropertyNamed:(NSString *)aName +{ + POPBasicAnimation *anim = [self animation]; + anim.property = [POPAnimatableProperty propertyWithName:aName]; + return anim; +} + +- (void)_initState +{ + _state = new POPBasicAnimationState(self); +} + ++ (instancetype)linearAnimation +{ + POPBasicAnimation *anim = [self animation]; + anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; + return anim; +} + ++ (instancetype)easeInAnimation +{ + POPBasicAnimation *anim = [self animation]; + anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]; + return anim; +} + ++ (instancetype)easeOutAnimation +{ + POPBasicAnimation *anim = [self animation]; + anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut]; + return anim; +} + ++ (instancetype)easeInEaseOutAnimation +{ + POPBasicAnimation *anim = [self animation]; + anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; + return anim; +} + ++ (instancetype)defaultAnimation +{ + POPBasicAnimation *anim = [self animation]; + anim.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault]; + return anim; +} + +- (id)init +{ + return [self _init]; +} + +#pragma mark - Properties + +DEFINE_RW_PROPERTY(POPBasicAnimationState, duration, setDuration:, CFTimeInterval); +DEFINE_RW_PROPERTY_OBJ(POPBasicAnimationState, timingFunction, setTimingFunction:, CAMediaTimingFunction*, __state->updatedTimingFunction();); + +#pragma mark - Utility + +- (void)_appendDescription:(NSMutableString *)s debug:(BOOL)debug +{ + [super _appendDescription:s debug:debug]; + if (__state->duration) + [s appendFormat:@"; duration = %f", __state->duration]; +} + +@end diff --git a/Example/Pods/pop/pop/POPBasicAnimationInternal.h b/Example/Pods/pop/pop/POPBasicAnimationInternal.h new file mode 100644 index 0000000..e274c3f --- /dev/null +++ b/Example/Pods/pop/pop/POPBasicAnimationInternal.h @@ -0,0 +1,96 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#import "POPBasicAnimation.h" +#import "POPPropertyAnimationInternal.h" + +// default animation duration +static CGFloat const kPOPAnimationDurationDefault = 0.4; + +// progress threshold for computing done +static CGFloat const kPOPProgressThreshold = 1e-6; + +static void interpolate(POPValueType valueType, NSUInteger count, const CGFloat *fromVec, const CGFloat *toVec, CGFloat *outVec, CGFloat p) +{ + switch (valueType) { + case kPOPValueInteger: + case kPOPValueFloat: + case kPOPValuePoint: + case kPOPValueSize: + case kPOPValueRect: + case kPOPValueEdgeInsets: + case kPOPValueColor: + POPInterpolateVector(count, outVec, fromVec, toVec, p); + break; + default: + NSCAssert(false, @"unhandled type %d", valueType); + break; + } +} + +struct _POPBasicAnimationState : _POPPropertyAnimationState +{ + CAMediaTimingFunction *timingFunction; + double timingControlPoints[4]; + CFTimeInterval duration; + CFTimeInterval timeProgress; + + _POPBasicAnimationState(id __unsafe_unretained anim) : _POPPropertyAnimationState(anim), + timingFunction(nil), + timingControlPoints{0.}, + duration(kPOPAnimationDurationDefault), + timeProgress(0.) + { + type = kPOPAnimationBasic; + } + + bool isDone() { + if (_POPPropertyAnimationState::isDone()) { + return true; + } + return timeProgress + kPOPProgressThreshold >= 1.; + } + + void updatedTimingFunction() + { + float vec[4] = {0.}; + [timingFunction getControlPointAtIndex:1 values:&vec[0]]; + [timingFunction getControlPointAtIndex:2 values:&vec[2]]; + for (NSUInteger idx = 0; idx < POP_ARRAY_COUNT(vec); idx++) { + timingControlPoints[idx] = vec[idx]; + } + } + + bool advance(CFTimeInterval time, CFTimeInterval dt, id obj) { + // default timing function + if (!timingFunction) { + ((POPBasicAnimation *)self).timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault]; + } + + // solve for normalized time, aka progresss [0, 1] + CGFloat p = 1.0f; + if (duration > 0.0f) { + // cap local time to duration + CFTimeInterval t = MIN(time - startTime, duration) / duration; + p = POPTimingFunctionSolve(timingControlPoints, t, SOLVE_EPS(duration)); + timeProgress = t; + } else { + timeProgress = 1.; + } + + // interpolate and advance + interpolate(valueType, valueCount, fromVec->data(), toVec->data(), currentVec->data(), p); + progress = p; + clampCurrentValue(); + + return true; + } +}; + +typedef struct _POPBasicAnimationState POPBasicAnimationState; diff --git a/Example/Pods/pop/pop/POPCGUtils.h b/Example/Pods/pop/pop/POPCGUtils.h new file mode 100644 index 0000000..f754d66 --- /dev/null +++ b/Example/Pods/pop/pop/POPCGUtils.h @@ -0,0 +1,107 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#import +#if TARGET_OS_IPHONE +#import +#endif +#import "POPDefines.h" + +#if TARGET_OS_IPHONE +@class UIColor; +#endif + +POP_EXTERN_C_BEGIN + +NS_INLINE CGPoint values_to_point(const CGFloat values[]) +{ + return CGPointMake(values[0], values[1]); +} + +NS_INLINE CGSize values_to_size(const CGFloat values[]) +{ + return CGSizeMake(values[0], values[1]); +} + +NS_INLINE CGRect values_to_rect(const CGFloat values[]) +{ + return CGRectMake(values[0], values[1], values[2], values[3]); +} + +#if TARGET_OS_IPHONE + +NS_INLINE UIEdgeInsets values_to_edge_insets(const CGFloat values[]) +{ + return UIEdgeInsetsMake(values[0], values[1], values[2], values[3]); +} + +#endif + +NS_INLINE void values_from_point(CGFloat values[], CGPoint p) +{ + values[0] = p.x; + values[1] = p.y; +} + +NS_INLINE void values_from_size(CGFloat values[], CGSize s) +{ + values[0] = s.width; + values[1] = s.height; +} + +NS_INLINE void values_from_rect(CGFloat values[], CGRect r) +{ + values[0] = r.origin.x; + values[1] = r.origin.y; + values[2] = r.size.width; + values[3] = r.size.height; +} + +#if TARGET_OS_IPHONE + +NS_INLINE void values_from_edge_insets(CGFloat values[], UIEdgeInsets i) +{ + values[0] = i.top; + values[1] = i.left; + values[2] = i.bottom; + values[3] = i.right; +} + +#endif + +/** + Takes a CGColorRef and converts it into RGBA components, if necessary. + */ +extern void POPCGColorGetRGBAComponents(CGColorRef color, CGFloat components[]); + +/** + Takes RGBA components and returns a CGColorRef. + */ +extern CGColorRef POPCGColorRGBACreate(const CGFloat components[]) CF_RETURNS_RETAINED; + +/** + Takes a color reference and returns a CGColor. + */ +extern CGColorRef POPCGColorWithColor(id color); + +#if TARGET_OS_IPHONE + +/** + Takes a UIColor and converts it into RGBA components, if necessary. + */ +extern void POPUIColorGetRGBAComponents(UIColor *color, CGFloat components[]); + +/** + Takes RGBA components and returns a UIColor. + */ +extern UIColor *POPUIColorRGBACreate(const CGFloat components[]) NS_RETURNS_RETAINED; + +#endif + +POP_EXTERN_C_END diff --git a/Example/Pods/pop/pop/POPCGUtils.mm b/Example/Pods/pop/pop/POPCGUtils.mm new file mode 100644 index 0000000..c8a866a --- /dev/null +++ b/Example/Pods/pop/pop/POPCGUtils.mm @@ -0,0 +1,96 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#import "POPCGUtils.h" + +#if TARGET_OS_IPHONE +#import +#else +#import +#endif + +void POPCGColorGetRGBAComponents(CGColorRef color, CGFloat components[]) +{ + if (!color) { +#if TARGET_OS_IPHONE + color = [UIColor clearColor].CGColor; +#else + color = [NSColor clearColor].CGColor; +#endif + } + + const CGFloat *colors = CGColorGetComponents(color); + size_t count = CGColorGetNumberOfComponents(color); + + if (4 == count) { + // RGB colorspace + components[0] = colors[0]; + components[1] = colors[1]; + components[2] = colors[2]; + components[3] = colors[3]; + } else if (2 == count) { + // Grey colorspace + components[0] = components[1] = components[2] = colors[0]; + components[3] = colors[1]; + } else { + // Use CI to convert + CIColor *ciColor = [CIColor colorWithCGColor:color]; + components[0] = ciColor.red; + components[1] = ciColor.green; + components[2] = ciColor.blue; + components[3] = ciColor.alpha; + } +} + +CGColorRef POPCGColorRGBACreate(const CGFloat components[]) +{ +#if TARGET_OS_IPHONE + CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB(); + CGColorRef color = CGColorCreate(space, components); + CGColorSpaceRelease(space); + return color; +#else + return CGColorCreateGenericRGB(components[0], components[1], components[2], components[3]); +#endif +} + +CGColorRef POPCGColorWithColor(id color) +{ + if (CFGetTypeID((__bridge CFTypeRef)color) == CGColorGetTypeID()) { + return ((__bridge CGColorRef)color); + } +#if TARGET_OS_IPHONE + else if ([color isKindOfClass:[UIColor class]]) { + return [color CGColor]; + } +#else + else if ([color isKindOfClass:[NSColor class]]) { + return [color CGColor]; + } +#endif + return nil; +} + +#if TARGET_OS_IPHONE + +void POPUIColorGetRGBAComponents(UIColor *color, CGFloat components[]) +{ + return POPCGColorGetRGBAComponents(color.CGColor, components); +} + +UIColor *POPUIColorRGBACreate(const CGFloat components[]) +{ + CGColorRef colorRef = POPCGColorRGBACreate(components); + UIColor *color = [[UIColor alloc] initWithCGColor:colorRef]; + CGColorRelease(colorRef); + return color; +} + +#endif + diff --git a/Example/Pods/pop/pop/POPCustomAnimation.h b/Example/Pods/pop/pop/POPCustomAnimation.h new file mode 100644 index 0000000..501a755 --- /dev/null +++ b/Example/Pods/pop/pop/POPCustomAnimation.h @@ -0,0 +1,46 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#import + +@class POPCustomAnimation; + +/** + @abstract POPCustomAnimationBlock is the callback block of a custom animation. + @discussion This block will be executed for each animation frame and should update the property or properties being animated based on current timing. + @param target The object being animated. Reference the passed in target to help avoid retain loops. + @param animation The custom animation instance. Use to determine the current and elapsed time since last callback. Reference the passed in animation to help avoid retain loops. + @return Flag indicating whether the animation should continue animating. Return NO to indicate animation is done. + */ +typedef BOOL (^POPCustomAnimationBlock)(id target, POPCustomAnimation *animation); + +/** + @abstract POPCustomAnimation is a concrete animation subclass for custom animations. + */ +@interface POPCustomAnimation : POPAnimation + +/** +@abstract Creates and returns an initialized custom animation instance. +@discussion This is the designated initializer. +@param block The custom animation callback block. See {@ref POPCustomAnimationBlock}. +@return The initialized custom animation instance. +*/ ++ (instancetype)animationWithBlock:(POPCustomAnimationBlock)block; + +/** + @abstract The current animation time at time of callback. + */ +@property (readonly, nonatomic) CFTimeInterval currentTime; + +/** + @abstract The elapsed animation time since last callback. + */ +@property (readonly, nonatomic) CFTimeInterval elapsedTime; + +@end diff --git a/Example/Pods/pop/pop/POPCustomAnimation.mm b/Example/Pods/pop/pop/POPCustomAnimation.mm new file mode 100644 index 0000000..20e361a --- /dev/null +++ b/Example/Pods/pop/pop/POPCustomAnimation.mm @@ -0,0 +1,56 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#import "POPCustomAnimation.h" +#import "POPAnimationInternal.h" + +@interface POPCustomAnimation () +@property (nonatomic, copy) POPCustomAnimationBlock animate; +@end + +@implementation POPCustomAnimation +@synthesize currentTime = _currentTime; +@synthesize elapsedTime = _elapsedTime; +@synthesize animate = _animate; + ++ (instancetype)animationWithBlock:(BOOL(^)(id target, POPCustomAnimation *))block +{ + POPCustomAnimation *b = [[self alloc] _init]; + b.animate = block; + return b; +} + +- (id)_init +{ + self = [super _init]; + if (nil != self) { + _state->type = kPOPAnimationCustom; + } + return self; +} + +- (CFTimeInterval)beginTime +{ + POPAnimationState *s = POPAnimationGetState(self); + return s->startTime > 0 ? s->startTime : s->beginTime; +} + +- (BOOL)_advance:(id)object currentTime:(CFTimeInterval)currentTime elapsedTime:(CFTimeInterval)elapsedTime +{ + _currentTime = currentTime; + _elapsedTime = elapsedTime; + return _animate(object, self); +} + +- (void)_appendDescription:(NSMutableString *)s debug:(BOOL)debug +{ + [s appendFormat:@"; elapsedTime = %f; currentTime = %f;", _elapsedTime, _currentTime]; +} + +@end diff --git a/Example/Pods/pop/pop/POPDecayAnimation.h b/Example/Pods/pop/pop/POPDecayAnimation.h new file mode 100644 index 0000000..92c6b60 --- /dev/null +++ b/Example/Pods/pop/pop/POPDecayAnimation.h @@ -0,0 +1,66 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#import + +/** + @abstract A concrete decay animation class. + @discussion Animation is achieved through gradual decay of animation value. + */ +@interface POPDecayAnimation : POPPropertyAnimation + +/** + @abstract The designated initializer. + @returns An instance of a decay animation. + */ ++ (instancetype)animation; + +/** + @abstract Convenience initializer that returns an animation with animatable property of name. + @param name The name of the animatable property. + @returns An instance of a decay animation configured with specified animatable property. + */ ++ (instancetype)animationWithPropertyNamed:(NSString *)name; + +/** + @abstract The current velocity value. + @discussion Set before animation start to account for initial velocity. Expressed in change of value units per second. The only POPValueTypes supported for velocity are: kPOPValuePoint, kPOPValueInteger, kPOPValueFloat, kPOPValueRect, and kPOPValueSize. + */ +@property (copy, nonatomic) id velocity; + +/** + @abstract The original velocity value. + @discussion Since the velocity property is modified as the animation progresses, this property stores the original, passed in velocity to support autoreverse and repeatCount. + */ +@property (copy, nonatomic, readonly) id originalVelocity; + +/** + @abstract The deceleration factor. + @discussion Values specifies should be in the range [0, 1]. Lower values results in faster deceleration. Defaults to 0.998. + */ +@property (assign, nonatomic) CGFloat deceleration; + +/** + @abstract The expected duration. + @discussion Derived based on input velocity and deceleration values. + */ +@property (readonly, assign, nonatomic) CFTimeInterval duration; + +/** + The to value is derived based on input velocity and deceleration. + */ +- (void)setToValue:(id)toValue NS_UNAVAILABLE; + +/** + @abstract The reversed velocity. + @discussion The reversed velocity based on the originalVelocity when the animation was set up. + */ +- (id)reversedVelocity; + +@end diff --git a/Example/Pods/pop/pop/POPDecayAnimation.mm b/Example/Pods/pop/pop/POPDecayAnimation.mm new file mode 100644 index 0000000..405c529 --- /dev/null +++ b/Example/Pods/pop/pop/POPDecayAnimation.mm @@ -0,0 +1,181 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#import "POPDecayAnimationInternal.h" + +#if TARGET_OS_IPHONE +#import +#endif + +const POPValueType supportedVelocityTypes[6] = { kPOPValuePoint, kPOPValueInteger, kPOPValueFloat, kPOPValueRect, kPOPValueSize, kPOPValueEdgeInsets }; + +@implementation POPDecayAnimation + +#pragma mark - Lifecycle + +#undef __state +#define __state ((POPDecayAnimationState *)_state) + ++ (instancetype)animation +{ + return [[self alloc] init]; +} + ++ (instancetype)animationWithPropertyNamed:(NSString *)aName +{ + POPDecayAnimation *anim = [self animation]; + anim.property = [POPAnimatableProperty propertyWithName:aName]; + return anim; +} + +- (id)init +{ + return [self _init]; +} + +- (void)_initState +{ + _state = new POPDecayAnimationState(self); +} + +#pragma mark - Properties + +DEFINE_RW_PROPERTY(POPDecayAnimationState, deceleration, setDeceleration:, CGFloat, __state->toVec = NULL;); + +@dynamic velocity; + +- (id)toValue +{ + [self _ensureComputedProperties]; + return POPBox(__state->toVec, __state->valueType); +} + +- (CFTimeInterval)duration +{ + [self _ensureComputedProperties]; + return __state->duration; +} + +- (void)setFromValue:(id)fromValue +{ + super.fromValue = fromValue; + [self _invalidateComputedProperties]; +} + +- (void)setToValue:(id)aValue +{ + // no-op + NSLog(@"ignoring to value on decay animation %@", self); +} + +- (id)reversedVelocity +{ + id reversedVelocity = nil; + + POPValueType velocityType = POPSelectValueType(self.originalVelocity, supportedVelocityTypes, POP_ARRAY_COUNT(supportedVelocityTypes)); + if (velocityType == kPOPValueFloat) { + CGFloat originalVelocityFloat = [(NSNumber *)self.originalVelocity floatValue]; + NSNumber *negativeOriginalVelocityNumber = @(-originalVelocityFloat); + reversedVelocity = negativeOriginalVelocityNumber; + } else if (velocityType == kPOPValueInteger) { + NSInteger originalVelocityInteger = [(NSNumber *)self.originalVelocity integerValue]; + NSNumber *negativeOriginalVelocityNumber = @(-originalVelocityInteger); + reversedVelocity = negativeOriginalVelocityNumber; + } else if (velocityType == kPOPValuePoint) { + CGPoint originalVelocityPoint = [self.originalVelocity CGPointValue]; + CGPoint negativeOriginalVelocityPoint = CGPointMake(-originalVelocityPoint.x, -originalVelocityPoint.y); + reversedVelocity = [NSValue valueWithCGPoint:negativeOriginalVelocityPoint]; + } else if (velocityType == kPOPValueRect) { + CGRect originalVelocityRect = [self.originalVelocity CGRectValue]; + CGRect negativeOriginalVelocityRect = CGRectMake(-originalVelocityRect.origin.x, -originalVelocityRect.origin.y, -originalVelocityRect.size.width, -originalVelocityRect.size.height); + reversedVelocity = [NSValue valueWithCGRect:negativeOriginalVelocityRect]; + } else if (velocityType == kPOPValueSize) { + CGSize originalVelocitySize = [self.originalVelocity CGSizeValue]; + CGSize negativeOriginalVelocitySize = CGSizeMake(-originalVelocitySize.width, -originalVelocitySize.height); + reversedVelocity = [NSValue valueWithCGSize:negativeOriginalVelocitySize]; + } else if (velocityType == kPOPValueEdgeInsets) { +#if TARGET_OS_IPHONE + UIEdgeInsets originalVelocityInsets = [self.originalVelocity UIEdgeInsetsValue]; + UIEdgeInsets negativeOriginalVelocityInsets = UIEdgeInsetsMake(-originalVelocityInsets.top, -originalVelocityInsets.left, -originalVelocityInsets.bottom, -originalVelocityInsets.right); + reversedVelocity = [NSValue valueWithUIEdgeInsets:negativeOriginalVelocityInsets]; +#endif + } + + return reversedVelocity; +} + +- (id)originalVelocity +{ + return POPBox(__state->originalVelocityVec, __state->valueType); +} + +- (id)velocity +{ + return POPBox(__state->velocityVec, __state->valueType); +} + +- (void)setVelocity:(id)aValue +{ + POPValueType valueType = POPSelectValueType(aValue, supportedVelocityTypes, POP_ARRAY_COUNT(supportedVelocityTypes)); + if (valueType != kPOPValueUnknown) { + VectorRef vec = POPUnbox(aValue, __state->valueType, __state->valueCount, YES); + VectorRef origVec = POPUnbox(aValue, __state->valueType, __state->valueCount, YES); + + if (!vec_equal(vec, __state->velocityVec)) { + __state->velocityVec = vec; + __state->originalVelocityVec = origVec; + + if (__state->tracing) { + [__state->tracer updateVelocity:aValue]; + } + + [self _invalidateComputedProperties]; + + // automatically unpause active animations + if (__state->active && __state->paused) { + __state->fromVec = NULL; + __state->setPaused(false); + } + } + } else { + __state->velocityVec = NULL; + NSLog(@"Invalid velocity value for the decayAnimation: %@", aValue); + } +} + +#pragma mark - Utility + +- (void)_ensureComputedProperties +{ + if (NULL == __state->toVec) { + __state->computeDuration(); + __state->computeToValue(); + } +} + +- (void)_invalidateComputedProperties +{ + __state->toVec = NULL; + __state->duration = 0; +} + +- (void)_appendDescription:(NSMutableString *)s debug:(BOOL)debug +{ + [super _appendDescription:s debug:debug]; + + if (0 != self.duration) { + [s appendFormat:@"; duration = %f", self.duration]; + } + + if (__state->deceleration) { + [s appendFormat:@"; deceleration = %f", __state->deceleration]; + } +} + +@end diff --git a/Example/Pods/pop/pop/POPDecayAnimationInternal.h b/Example/Pods/pop/pop/POPDecayAnimationInternal.h new file mode 100644 index 0000000..6b2d854 --- /dev/null +++ b/Example/Pods/pop/pop/POPDecayAnimationInternal.h @@ -0,0 +1,158 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#import "POPDecayAnimation.h" +#import "POPPropertyAnimationInternal.h" + +// minimal velocity factor before decay animation is considered complete, in units / s +static CGFloat kPOPAnimationDecayMinimalVelocityFactor = 5.; + +// default decay animation deceleration +static CGFloat kPOPAnimationDecayDecelerationDefault = 0.998; + +static void decay_position(CGFloat *x, CGFloat *v, NSUInteger count, CFTimeInterval dt, CGFloat deceleration) +{ + dt *= 1000; + + // v0 = v / 1000 + // v = v0 * powf(deceleration, dt); + // v = v * 1000; + + // x0 = x; + // x = x0 + v0 * deceleration * (1 - powf(deceleration, dt)) / (1 - deceleration) + float v0[count]; + float kv = powf(deceleration, dt); + float kx = deceleration * (1 - kv) / (1 - deceleration); + + for (NSUInteger idx = 0; idx < count; idx++) { + v0[idx] = v[idx] / 1000.; + v[idx] = v0[idx] * kv * 1000.; + x[idx] = x[idx] + v0[idx] * kx; + } +} + +struct _POPDecayAnimationState : _POPPropertyAnimationState +{ + double deceleration; + CFTimeInterval duration; + + _POPDecayAnimationState(id __unsafe_unretained anim) : + _POPPropertyAnimationState(anim), + deceleration(kPOPAnimationDecayDecelerationDefault), + duration(0) + { + type = kPOPAnimationDecay; + } + + bool isDone() { + if (_POPPropertyAnimationState::isDone()) { + return true; + } + + CGFloat f = dynamicsThreshold * kPOPAnimationDecayMinimalVelocityFactor; + const CGFloat *velocityValues = vec_data(velocityVec); + for (NSUInteger idx = 0; idx < valueCount; idx++) { + if (fabsf(velocityValues[idx]) >= f) + return false; + } + return true; + + } + + void computeDuration() { + + // compute duration till threshold velocity + Vector4r scaledVelocity = vector4(velocityVec) / 1000.; + + double k = dynamicsThreshold * kPOPAnimationDecayMinimalVelocityFactor / 1000.; + double vx = k / scaledVelocity.x; + double vy = k / scaledVelocity.y; + double vz = k / scaledVelocity.z; + double vw = k / scaledVelocity.w; + double d = log(deceleration) * 1000.; + duration = MAX(MAX(MAX(log(fabs(vx)) / d, log(fabs(vy)) / d), log(fabs(vz)) / d), log(fabs(vw)) / d); + + // ensure velocity threshold is exceeded + if (isnan(duration) || duration < 0) { + duration = 0; + } + } + + void computeToValue() { + // to value assuming final velocity as a factor of dynamics threshold + // derived from v' = v * d^dt used in decay_position + // to compute the to value with maximal dt, p' = p + (v * d) / (1 - d) + VectorRef fromValue = NULL != currentVec ? currentVec : fromVec; + if (!fromValue) { + return; + } + + // ensure duration is computed + if (0 == duration) { + computeDuration(); + } + + // compute to value + VectorRef toValue(Vector::new_vector(fromValue.get())); + Vector4r velocity = velocityVec->vector4r(); + decay_position(toValue->data(), velocity.data(), valueCount, duration, deceleration); + toVec = toValue; + } + + void computeDestinationValues() { + // to value assuming final velocity as a factor of dynamics threshold + // derived from v' = v * d^dt used in decay_position + // to compute the to value with maximal dt, p' = p + (v * d) / (1 - d) + VectorRef fromValue = NULL != currentVec ? currentVec : fromVec; + if (!fromValue) { + return; + } + + VectorRef toValue(Vector::new_vector(fromValue.get())); + + // compute duration till threshold velocity + Vector4r scaledVelocity = vector4(velocityVec) / 1000.; + + double k = dynamicsThreshold * kPOPAnimationDecayMinimalVelocityFactor / 1000.; + double vx = k / scaledVelocity.x; + double vy = k / scaledVelocity.y; + double vz = k / scaledVelocity.z; + double vw = k / scaledVelocity.w; + double d = log(deceleration) * 1000.; + duration = MAX(MAX(MAX(log(fabs(vx)) / d, log(fabs(vy)) / d), log(fabs(vz)) / d), log(fabs(vw)) / d); + + // ensure velocity threshold is exceeded + if (isnan(duration) || duration < 0) { + duration = 0; + } else { + // compute to value + Vector4r velocity = velocityVec->vector4r(); + decay_position(toValue->data(), velocity.data(), valueCount, duration, deceleration); + } + + toVec = toValue; + } + + bool advance(CFTimeInterval time, CFTimeInterval dt, id obj) { + // advance past not yet initialized animations + if (NULL == currentVec) { + return false; + } + + decay_position(currentVec->data(), velocityVec->data(), valueCount, dt, deceleration); + + // clamp to compute end value; avoid possibility of decaying past + clampCurrentValue(kPOPAnimationClampEnd | clampMode); + + return true; + } + +}; + +typedef struct _POPDecayAnimationState POPDecayAnimationState; diff --git a/Example/Pods/pop/pop/POPDefines.h b/Example/Pods/pop/pop/POPDefines.h new file mode 100644 index 0000000..92cf801 --- /dev/null +++ b/Example/Pods/pop/pop/POPDefines.h @@ -0,0 +1,29 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#ifndef POP_POPDefines_h +#define POP_POPDefines_h + +#ifdef __cplusplus +# define POP_EXTERN_C_BEGIN extern "C" { +# define POP_EXTERN_C_END } +#else +# define POP_EXTERN_C_BEGIN +# define POP_EXTERN_C_END +#endif + +#define POP_ARRAY_COUNT(x) sizeof(x) / sizeof(x[0]) + +#if defined (__cplusplus) && defined (__GNUC__) +# define POP_NOTHROW __attribute__ ((nothrow)) +#else +# define POP_NOTHROW +#endif + +#endif diff --git a/Example/Pods/pop/pop/POPGeometry.h b/Example/Pods/pop/pop/POPGeometry.h new file mode 100644 index 0000000..8ba07e3 --- /dev/null +++ b/Example/Pods/pop/pop/POPGeometry.h @@ -0,0 +1,73 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#import + +#if TARGET_OS_IPHONE +#import +#endif + +#if !TARGET_OS_IPHONE + +/** NSValue extensions to support animatable types. */ +@interface NSValue (POP) + +/** + @abstract Creates an NSValue given a CGPoint. + */ ++ (NSValue *)valueWithCGPoint:(CGPoint)point; + +/** + @abstract Creates an NSValue given a CGSize. + */ ++ (NSValue *)valueWithCGSize:(CGSize)size; + +/** + @abstract Creates an NSValue given a CGRect. + */ ++ (NSValue *)valueWithCGRect:(CGRect)rect; + +/** + @abstract Creates an NSValue given a CFRange. + */ ++ (NSValue *)valueWithCFRange:(CFRange)range; + +/** + @abstract Creates an NSValue given a CGAffineTransform. + */ ++ (NSValue *)valueWithCGAffineTransform:(CGAffineTransform)transform; + +/** + @abstract Returns the underlying CGPoint value. + */ +- (CGPoint)CGPointValue; + +/** + @abstract Returns the underlying CGSize value. + */ +- (CGSize)CGSizeValue; + +/** + @abstract Returns the underlying CGRect value. + */ +- (CGRect)CGRectValue; + +/** + @abstract Returns the underlying CFRange value. + */ +- (CFRange)CFRangeValue; + +/** + @abstract Returns the underlying CGAffineTransform value. + */ +- (CGAffineTransform)CGAffineTransformValue; + +@end + +#endif diff --git a/Example/Pods/pop/pop/POPGeometry.mm b/Example/Pods/pop/pop/POPGeometry.mm new file mode 100644 index 0000000..29c75a4 --- /dev/null +++ b/Example/Pods/pop/pop/POPGeometry.mm @@ -0,0 +1,67 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#import "POPGeometry.h" + +#if !TARGET_OS_IPHONE +@implementation NSValue (POP) + ++ (NSValue *)valueWithCGPoint:(CGPoint)point { + return [NSValue valueWithBytes:&point objCType:@encode(CGPoint)]; +} + ++ (NSValue *)valueWithCGSize:(CGSize)size { + return [NSValue valueWithBytes:&size objCType:@encode(CGSize)]; +} + ++ (NSValue *)valueWithCGRect:(CGRect)rect { + return [NSValue valueWithBytes:&rect objCType:@encode(CGRect)]; +} + ++ (NSValue *)valueWithCFRange:(CFRange)range { + return [NSValue valueWithBytes:&range objCType:@encode(CFRange)]; +} + ++ (NSValue *)valueWithCGAffineTransform:(CGAffineTransform)transform +{ + return [NSValue valueWithBytes:&transform objCType:@encode(CGAffineTransform)]; +} + +- (CGPoint)CGPointValue { + CGPoint result; + [self getValue:&result]; + return result; +} + +- (CGSize)CGSizeValue { + CGSize result; + [self getValue:&result]; + return result; +} + +- (CGRect)CGRectValue { + CGRect result; + [self getValue:&result]; + return result; +} + +- (CFRange)CFRangeValue { + CFRange result; + [self getValue:&result]; + return result; +} + +- (CGAffineTransform)CGAffineTransformValue { + CGAffineTransform result; + [self getValue:&result]; + return result; +} +@end + +#endif diff --git a/Example/Pods/pop/pop/POPLayerExtras.h b/Example/Pods/pop/pop/POPLayerExtras.h new file mode 100644 index 0000000..ec4c29a --- /dev/null +++ b/Example/Pods/pop/pop/POPLayerExtras.h @@ -0,0 +1,196 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#import + +#import + +POP_EXTERN_C_BEGIN + +#pragma mark - Scale + +/** + @abstract Returns layer scale factor for the x axis. + */ +extern CGFloat POPLayerGetScaleX(CALayer *l); + +/** + @abstract Set layer scale factor for the x axis. + */ +extern void POPLayerSetScaleX(CALayer *l, CGFloat f); + +/** + @abstract Returns layer scale factor for the y axis. + */ +extern CGFloat POPLayerGetScaleY(CALayer *l); + +/** + @abstract Set layer scale factor for the y axis. + */ +extern void POPLayerSetScaleY(CALayer *l, CGFloat f); + +/** + @abstract Returns layer scale factor for the z axis. + */ +extern CGFloat POPLayerGetScaleZ(CALayer *l); + +/** + @abstract Set layer scale factor for the z axis. + */ +extern void POPLayerSetScaleZ(CALayer *l, CGFloat f); + +/** + @abstract Returns layer scale factors for x and y access as point. + */ +extern CGPoint POPLayerGetScaleXY(CALayer *l); + +/** + @abstract Sets layer x and y scale factors given point. + */ +extern void POPLayerSetScaleXY(CALayer *l, CGPoint p); + +#pragma mark - Translation + +/** + @abstract Returns layer translation factor for the x axis. + */ +extern CGFloat POPLayerGetTranslationX(CALayer *l); + +/** + @abstract Set layer translation factor for the x axis. + */ +extern void POPLayerSetTranslationX(CALayer *l, CGFloat f); + +/** + @abstract Returns layer translation factor for the y axis. + */ +extern CGFloat POPLayerGetTranslationY(CALayer *l); + +/** + @abstract Set layer translation factor for the y axis. + */ +extern void POPLayerSetTranslationY(CALayer *l, CGFloat f); + +/** + @abstract Returns layer translation factor for the z axis. + */ +extern CGFloat POPLayerGetTranslationZ(CALayer *l); + +/** + @abstract Set layer translation factor for the z axis. + */ +extern void POPLayerSetTranslationZ(CALayer *l, CGFloat f); + +/** + @abstract Returns layer translation factors for x and y access as point. + */ +extern CGPoint POPLayerGetTranslationXY(CALayer *l); + +/** + @abstract Sets layer x and y translation factors given point. + */ +extern void POPLayerSetTranslationXY(CALayer *l, CGPoint p); + +#pragma mark - Rotation + +/** + @abstract Returns layer rotation, in radians, in the X axis. + */ +extern CGFloat POPLayerGetRotationX(CALayer *l); + +/** + @abstract Sets layer rotation, in radians, in the X axis. + */ +extern void POPLayerSetRotationX(CALayer *l, CGFloat f); + +/** + @abstract Returns layer rotation, in radians, in the Y axis. + */ +extern CGFloat POPLayerGetRotationY(CALayer *l); + +/** + @abstract Sets layer rotation, in radians, in the Y axis. + */ +extern void POPLayerSetRotationY(CALayer *l, CGFloat f); + +/** + @abstract Returns layer rotation, in radians, in the Z axis. + */ +extern CGFloat POPLayerGetRotationZ(CALayer *l); + +/** + @abstract Sets layer rotation, in radians, in the Z axis. + */ +extern void POPLayerSetRotationZ(CALayer *l, CGFloat f); + +/** + @abstract Returns layer rotation, in radians, in the Z axis. + */ +extern CGFloat POPLayerGetRotation(CALayer *l); + +/** + @abstract Sets layer rotation, in radians, in the Z axis. + */ +extern void POPLayerSetRotation(CALayer *l, CGFloat f); + +#pragma mark - Sublayer Scale + +/** + @abstract Returns sublayer scale factors for x and y access as point. + */ +extern CGPoint POPLayerGetSubScaleXY(CALayer *l); + +/** + @abstract Sets sublayer x and y scale factors given point. + */ +extern void POPLayerSetSubScaleXY(CALayer *l, CGPoint p); + +#pragma mark - Sublayer Translation + +/** + @abstract Returns sublayer translation factor for the x axis. + */ +extern CGFloat POPLayerGetSubTranslationX(CALayer *l); + +/** + @abstract Set sublayer translation factor for the x axis. + */ +extern void POPLayerSetSubTranslationX(CALayer *l, CGFloat f); + +/** + @abstract Returns sublayer translation factor for the y axis. + */ +extern CGFloat POPLayerGetSubTranslationY(CALayer *l); + +/** + @abstract Set sublayer translation factor for the y axis. + */ +extern void POPLayerSetSubTranslationY(CALayer *l, CGFloat f); + +/** + @abstract Returns sublayer translation factor for the z axis. + */ +extern CGFloat POPLayerGetSubTranslationZ(CALayer *l); + +/** + @abstract Set sublayer translation factor for the z axis. + */ +extern void POPLayerSetSubTranslationZ(CALayer *l, CGFloat f); + +/** + @abstract Returns sublayer translation factors for x and y access as point. + */ +extern CGPoint POPLayerGetSubTranslationXY(CALayer *l); + +/** + @abstract Sets sublayer x and y translation factors given point. + */ +extern void POPLayerSetSubTranslationXY(CALayer *l, CGPoint p); + +POP_EXTERN_C_END diff --git a/Example/Pods/pop/pop/POPLayerExtras.mm b/Example/Pods/pop/pop/POPLayerExtras.mm new file mode 100644 index 0000000..c8ad7f9 --- /dev/null +++ b/Example/Pods/pop/pop/POPLayerExtras.mm @@ -0,0 +1,288 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#import "POPLayerExtras.h" + +#include "TransformationMatrix.h" + +using namespace WebCore; + +#define DECOMPOSE_TRANSFORM(L) \ + TransformationMatrix _m(L.transform); \ + TransformationMatrix::DecomposedType _d; \ + _m.decompose(_d); + +#define RECOMPOSE_TRANSFORM(L) \ + _m.recompose(_d); \ + L.transform = _m.transform3d(); + +#define RECOMPOSE_ROT_TRANSFORM(L) \ + _m.recompose(_d, true); \ + L.transform = _m.transform3d(); + +#define DECOMPOSE_SUBLAYER_TRANSFORM(L) \ + TransformationMatrix _m(L.sublayerTransform); \ + TransformationMatrix::DecomposedType _d; \ + _m.decompose(_d); + +#define RECOMPOSE_SUBLAYER_TRANSFORM(L) \ + _m.recompose(_d); \ + L.sublayerTransform = _m.transform3d(); + +#pragma mark - Scale + +NS_INLINE void ensureNonZeroValue(CGFloat &f) +{ + if (f == 0) { + f = 1e-6; + } +} + +NS_INLINE void ensureNonZeroValue(CGPoint &p) +{ + if (p.x == 0 && p.y == 0) { + p.x = 1e-6; + p.y = 1e-6; + } +} + +CGFloat POPLayerGetScaleX(CALayer *l) +{ + DECOMPOSE_TRANSFORM(l); + return _d.scaleX; +} + +void POPLayerSetScaleX(CALayer *l, CGFloat f) +{ + ensureNonZeroValue(f); + DECOMPOSE_TRANSFORM(l); + _d.scaleX = f; + RECOMPOSE_TRANSFORM(l); +} + +CGFloat POPLayerGetScaleY(CALayer *l) +{ + DECOMPOSE_TRANSFORM(l); + return _d.scaleY; +} + +void POPLayerSetScaleY(CALayer *l, CGFloat f) +{ + ensureNonZeroValue(f); + DECOMPOSE_TRANSFORM(l); + _d.scaleY = f; + RECOMPOSE_TRANSFORM(l); +} + +CGFloat POPLayerGetScaleZ(CALayer *l) +{ + DECOMPOSE_TRANSFORM(l); + return _d.scaleZ; +} + +void POPLayerSetScaleZ(CALayer *l, CGFloat f) +{ + ensureNonZeroValue(f); + DECOMPOSE_TRANSFORM(l); + _d.scaleZ = f; + RECOMPOSE_TRANSFORM(l); +} + +CGPoint POPLayerGetScaleXY(CALayer *l) +{ + DECOMPOSE_TRANSFORM(l); + return CGPointMake(_d.scaleX, _d.scaleY); +} + +void POPLayerSetScaleXY(CALayer *l, CGPoint p) +{ + ensureNonZeroValue(p); + DECOMPOSE_TRANSFORM(l); + _d.scaleX = p.x; + _d.scaleY = p.y; + RECOMPOSE_TRANSFORM(l); +} + +#pragma mark - Translation + +CGFloat POPLayerGetTranslationX(CALayer *l) +{ + DECOMPOSE_TRANSFORM(l); + return _d.translateX; +} + +void POPLayerSetTranslationX(CALayer *l, CGFloat f) +{ + DECOMPOSE_TRANSFORM(l); + _d.translateX = f; + RECOMPOSE_TRANSFORM(l); +} + +CGFloat POPLayerGetTranslationY(CALayer *l) +{ + DECOMPOSE_TRANSFORM(l); + return _d.translateY; +} + +void POPLayerSetTranslationY(CALayer *l, CGFloat f) +{ + DECOMPOSE_TRANSFORM(l); + _d.translateY = f; + RECOMPOSE_TRANSFORM(l); +} + +CGFloat POPLayerGetTranslationZ(CALayer *l) +{ + DECOMPOSE_TRANSFORM(l); + return _d.translateZ; +} + +void POPLayerSetTranslationZ(CALayer *l, CGFloat f) +{ + DECOMPOSE_TRANSFORM(l); + _d.translateZ = f; + RECOMPOSE_TRANSFORM(l); +} + +CGPoint POPLayerGetTranslationXY(CALayer *l) +{ + DECOMPOSE_TRANSFORM(l); + return CGPointMake(_d.translateX, _d.translateY); +} + +void POPLayerSetTranslationXY(CALayer *l, CGPoint p) +{ + DECOMPOSE_TRANSFORM(l); + _d.translateX = p.x; + _d.translateY = p.y; + RECOMPOSE_TRANSFORM(l); +} + +#pragma mark - Rotation + +CGFloat POPLayerGetRotationX(CALayer *l) +{ + DECOMPOSE_TRANSFORM(l); + return _d.rotateX; +} + +void POPLayerSetRotationX(CALayer *l, CGFloat f) +{ + DECOMPOSE_TRANSFORM(l); + _d.rotateX = f; + RECOMPOSE_ROT_TRANSFORM(l); +} + +CGFloat POPLayerGetRotationY(CALayer *l) +{ + DECOMPOSE_TRANSFORM(l); + return _d.rotateY; +} + +void POPLayerSetRotationY(CALayer *l, CGFloat f) +{ + DECOMPOSE_TRANSFORM(l); + _d.rotateY = f; + RECOMPOSE_ROT_TRANSFORM(l); +} + +CGFloat POPLayerGetRotationZ(CALayer *l) +{ + DECOMPOSE_TRANSFORM(l); + return _d.rotateZ; +} + +void POPLayerSetRotationZ(CALayer *l, CGFloat f) +{ + DECOMPOSE_TRANSFORM(l); + _d.rotateZ = f; + RECOMPOSE_ROT_TRANSFORM(l); +} + +CGFloat POPLayerGetRotation(CALayer *l) +{ + return POPLayerGetRotationZ(l); +} + +void POPLayerSetRotation(CALayer *l, CGFloat f) +{ + POPLayerSetRotationZ(l, f); +} + +#pragma mark - Sublayer Scale + +CGPoint POPLayerGetSubScaleXY(CALayer *l) +{ + DECOMPOSE_SUBLAYER_TRANSFORM(l); + return CGPointMake(_d.scaleX, _d.scaleY); +} + +void POPLayerSetSubScaleXY(CALayer *l, CGPoint p) +{ + ensureNonZeroValue(p); + DECOMPOSE_SUBLAYER_TRANSFORM(l); + _d.scaleX = p.x; + _d.scaleY = p.y; + RECOMPOSE_SUBLAYER_TRANSFORM(l); +} + +#pragma mark - Sublayer Translation + +extern CGFloat POPLayerGetSubTranslationX(CALayer *l) +{ + DECOMPOSE_SUBLAYER_TRANSFORM(l); + return _d.translateX; +} + +extern void POPLayerSetSubTranslationX(CALayer *l, CGFloat f) +{ + DECOMPOSE_SUBLAYER_TRANSFORM(l); + _d.translateX = f; + RECOMPOSE_SUBLAYER_TRANSFORM(l); +} + +extern CGFloat POPLayerGetSubTranslationY(CALayer *l) +{ + DECOMPOSE_SUBLAYER_TRANSFORM(l); + return _d.translateY; +} + +extern void POPLayerSetSubTranslationY(CALayer *l, CGFloat f) +{ + DECOMPOSE_SUBLAYER_TRANSFORM(l); + _d.translateY = f; + RECOMPOSE_SUBLAYER_TRANSFORM(l); +} + +extern CGFloat POPLayerGetSubTranslationZ(CALayer *l) +{ + DECOMPOSE_SUBLAYER_TRANSFORM(l); + return _d.translateZ; +} + +extern void POPLayerSetSubTranslationZ(CALayer *l, CGFloat f) +{ + DECOMPOSE_SUBLAYER_TRANSFORM(l); + _d.translateZ = f; + RECOMPOSE_SUBLAYER_TRANSFORM(l); +} + +extern CGPoint POPLayerGetSubTranslationXY(CALayer *l) +{ + DECOMPOSE_SUBLAYER_TRANSFORM(l); + return CGPointMake(_d.translateX, _d.translateY); +} + +extern void POPLayerSetSubTranslationXY(CALayer *l, CGPoint p) +{ + DECOMPOSE_SUBLAYER_TRANSFORM(l); + _d.translateX = p.x; + _d.translateY = p.y; + RECOMPOSE_SUBLAYER_TRANSFORM(l); +} diff --git a/Example/Pods/pop/pop/POPMath.h b/Example/Pods/pop/pop/POPMath.h new file mode 100644 index 0000000..baba374 --- /dev/null +++ b/Example/Pods/pop/pop/POPMath.h @@ -0,0 +1,55 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#import +#import + +#import "POPDefines.h" +#import "POPVector.h" + +NS_INLINE CGFloat sqrtr(CGFloat f) +{ +#if CGFLOAT_IS_DOUBLE + return sqrt(f); +#else + return sqrtf(f); +#endif +} + +// round to nearest sub; pass 2.0 to round to every 0.5 (eg: retina pixels) +NS_INLINE CGFloat POPSubRound(CGFloat f, CGFloat sub) +{ + return round(f * sub) / sub; +} + +#define MIX(a, b, f) ((a) + (f) * ((b) - (a))) + +// the longer the duration, the higher the necessary precision +#define SOLVE_EPS(dur) (1. / (1000. * (dur))) + +#define _EQLF_(x, y, epsilon) (fabsf ((x) - (y)) < epsilon) + +extern void POPInterpolateVector(NSUInteger count, CGFloat *dst, const CGFloat *from, const CGFloat *to, CGFloat f); + +extern double POPTimingFunctionSolve(const double vec[4], double t, double eps); + +// quadratic mapping of t [0, 1] to [start, end] +extern double POPQuadraticOutInterpolation(double t, double start, double end); + +// normalize value to [0, 1] based on its range [startValue, endValue] +extern double POPNormalize(double value, double startValue, double endValue); + +// project a normalized value [0, 1] to a given range [start, end] +extern double POPProjectNormal(double n, double start, double end); + +// solve a quadratic equation of the form a * x^2 + b * x + c = 0 +extern void POPQuadraticSolve(CGFloat a, CGFloat b, CGFloat c, CGFloat &x1, CGFloat &x2); + +// for a given tension return the bouncy 3 friction that produces no bounce +extern double POPBouncy3NoBounce(double tension); diff --git a/Example/Pods/pop/pop/POPMath.mm b/Example/Pods/pop/pop/POPMath.mm new file mode 100644 index 0000000..5dbfd7d --- /dev/null +++ b/Example/Pods/pop/pop/POPMath.mm @@ -0,0 +1,82 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#import "POPMath.h" +#import "UnitBezier.h" +#import "POPAnimationPrivate.h" + +void POPInterpolateVector(NSUInteger count, CGFloat *dst, const CGFloat *from, const CGFloat *to, CGFloat f) +{ + for (NSUInteger idx = 0; idx < count; idx++) { + dst[idx] = MIX(from[idx], to[idx], f); + } +} + +double POPTimingFunctionSolve(const double vec[4], double t, double eps) +{ + WebCore::UnitBezier bezier(vec[0], vec[1], vec[2], vec[3]); + return bezier.solve(t, eps); +} + +double POPNormalize(double value, double startValue, double endValue) +{ + return (value - startValue) / (endValue - startValue); +} + +double POPProjectNormal(double n, double start, double end) +{ + return start + (n * (end - start)); +} + +static double linear_interpolation(double t, double start, double end) +{ + return t * end + (1.f - t) * start; +} + +double POPQuadraticOutInterpolation(double t, double start, double end) +{ + return linear_interpolation(2*t - t*t, start, end); +} + +static double b3_friction1(double x) +{ + return (0.0007 * pow(x, 3)) - (0.031 * pow(x, 2)) + 0.64 * x + 1.28; +} + +static double b3_friction2(double x) +{ + return (0.000044 * pow(x, 3)) - (0.006 * pow(x, 2)) + 0.36 * x + 2.; +} + +static double b3_friction3(double x) +{ + return (0.00000045 * pow(x, 3)) - (0.000332 * pow(x, 2)) + 0.1078 * x + 5.84; +} + +double POPBouncy3NoBounce(double tension) +{ + double friction = 0; + if (tension <= 18.) { + friction = b3_friction1(tension); + } else if (tension > 18 && tension <= 44) { + friction = b3_friction2(tension); + } else if (tension > 44) { + friction = b3_friction3(tension); + } else { + assert(false); + } + return friction; +} + +void POPQuadraticSolve(CGFloat a, CGFloat b, CGFloat c, CGFloat &x1, CGFloat &x2) +{ + CGFloat discriminant = sqrt(b * b - 4 * a * c); + x1 = (-b + discriminant) / (2 * a); + x2 = (-b - discriminant) / (2 * a); +} diff --git a/Example/Pods/pop/pop/POPPropertyAnimation.h b/Example/Pods/pop/pop/POPPropertyAnimation.h new file mode 100644 index 0000000..2861665 --- /dev/null +++ b/Example/Pods/pop/pop/POPPropertyAnimation.h @@ -0,0 +1,65 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#import +#import + +/** + @abstract Flags for clamping animation values. + @discussion Animation values can optionally be clamped to avoid overshoot. kPOPAnimationClampStart ensures values are more than fromValue and kPOPAnimationClampEnd ensures values are less than toValue. + */ +typedef NS_OPTIONS(NSUInteger, POPAnimationClampFlags) +{ + kPOPAnimationClampNone = 0, + kPOPAnimationClampStart = 1UL << 0, + kPOPAnimationClampEnd = 1UL << 1, + kPOPAnimationClampBoth = kPOPAnimationClampStart | kPOPAnimationClampEnd, +}; + +/** + @abstract The semi-concrete property animation subclass. + */ +@interface POPPropertyAnimation : POPAnimation + +/** + @abstract The property to animate. + */ +@property (strong, nonatomic) POPAnimatableProperty *property; + +/** + @abstract The value to animate from. + @discussion The value type should match the property. If unspecified, the value is initialized to the object's current value on animation start. + */ +@property (copy, nonatomic) id fromValue; + +/** + @abstract The value to animate to. + @discussion The value type should match the property. If unspecified, the value is initialized to the object's current value on animation start. + */ +@property (copy, nonatomic) id toValue; + +/** + @abstract The rounding factor applied to the current animated value. + @discussion Specify 1.0 to animate between integral values. Defaults to 0 meaning no rounding. + */ +@property (assign, nonatomic) CGFloat roundingFactor; + +/** + @abstract The clamp mode applied to the current animated value. + @discussion See {@ref POPAnimationClampFlags} for possible values. Defaults to kPOPAnimationClampNone. + */ +@property (assign, nonatomic) NSUInteger clampMode; + +/** + @abstract The flag indicating whether values should be "added" each frame, rather than set. + @discussion Addition may be type dependent. Defaults to NO. + */ +@property (assign, nonatomic, getter = isAdditive) BOOL additive; + +@end diff --git a/Example/Pods/pop/pop/POPPropertyAnimation.mm b/Example/Pods/pop/pop/POPPropertyAnimation.mm new file mode 100644 index 0000000..118e689 --- /dev/null +++ b/Example/Pods/pop/pop/POPPropertyAnimation.mm @@ -0,0 +1,105 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#import "POPPropertyAnimationInternal.h" + +@implementation POPPropertyAnimation + +#pragma mark - Lifecycle + +#undef __state +#define __state ((POPPropertyAnimationState *)_state) + +- (void)_initState +{ + _state = new POPPropertyAnimationState(self); +} + +#pragma mark - Properties + +DEFINE_RW_FLAG(POPPropertyAnimationState, additive, isAdditive, setAdditive:); +DEFINE_RW_PROPERTY(POPPropertyAnimationState, roundingFactor, setRoundingFactor:, CGFloat); +DEFINE_RW_PROPERTY(POPPropertyAnimationState, clampMode, setClampMode:, NSUInteger); +DEFINE_RW_PROPERTY_OBJ(POPPropertyAnimationState, property, setProperty:, POPAnimatableProperty*, ((POPPropertyAnimationState*)_state)->updatedDynamicsThreshold();); +DEFINE_RW_PROPERTY_OBJ_COPY(POPPropertyAnimationState, progressMarkers, setProgressMarkers:, NSArray*, ((POPPropertyAnimationState*)_state)->updatedProgressMarkers();); + +- (id)fromValue +{ + return POPBox(__state->fromVec, __state->valueType); +} + +- (void)setFromValue:(id)aValue +{ + POPPropertyAnimationState *s = __state; + VectorRef vec = POPUnbox(aValue, s->valueType, s->valueCount, YES); + if (!vec_equal(vec, s->fromVec)) { + s->fromVec = vec; + + if (s->tracing) { + [s->tracer updateFromValue:aValue]; + } + } +} + +- (id)toValue +{ + return POPBox(__state->toVec, __state->valueType); +} + +- (void)setToValue:(id)aValue +{ + POPPropertyAnimationState *s = __state; + VectorRef vec = POPUnbox(aValue, s->valueType, s->valueCount, YES); + + if (!vec_equal(vec, s->toVec)) { + s->toVec = vec; + + // invalidate to dependent state + s->didReachToValue = false; + s->distanceVec = NULL; + + if (s->tracing) { + [s->tracer updateToValue:aValue]; + } + + // automatically unpause active animations + if (s->active && s->paused) { + s->setPaused(false); + } + } +} + +- (id)currentValue +{ + return POPBox(__state->currentValue(), __state->valueType); +} + +#pragma mark - Utility + +- (void)_appendDescription:(NSMutableString *)s debug:(BOOL)debug +{ + [s appendFormat:@"; from = %@; to = %@", describe(__state->fromVec), describe(__state->toVec)]; + + if (_state->active) + [s appendFormat:@"; currentValue = %@", describe(__state->currentValue())]; + + if (__state->velocityVec && 0 != __state->velocityVec->norm()) + [s appendFormat:@"; velocity = %@", describe(__state->velocityVec)]; + + if (!self.removedOnCompletion) + [s appendFormat:@"; removedOnCompletion = %@", POPStringFromBOOL(self.removedOnCompletion)]; + + if (__state->progressMarkers) + [s appendFormat:@"; progressMarkers = [%@]", [__state->progressMarkers componentsJoinedByString:@", "]]; + + if (_state->active) + [s appendFormat:@"; progress = %f", __state->progress]; +} + +@end diff --git a/Example/Pods/pop/pop/POPPropertyAnimationInternal.h b/Example/Pods/pop/pop/POPPropertyAnimationInternal.h new file mode 100644 index 0000000..a6758c8 --- /dev/null +++ b/Example/Pods/pop/pop/POPPropertyAnimationInternal.h @@ -0,0 +1,353 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#import "POPAnimationInternal.h" +#import "POPPropertyAnimation.h" + +static void clampValue(CGFloat &value, CGFloat fromValue, CGFloat toValue, NSUInteger clamp) +{ + BOOL increasing = (toValue > fromValue); + + // Clamp start of animation. + if ((kPOPAnimationClampStart & clamp) && + ((increasing && (value < fromValue)) || (!increasing && (value > fromValue)))) { + value = fromValue; + } + + // Clamp end of animation. + if ((kPOPAnimationClampEnd & clamp) && + ((increasing && (value > toValue)) || (!increasing && (value < toValue)))) { + value = toValue; + } +} + +struct _POPPropertyAnimationState : _POPAnimationState +{ + POPAnimatableProperty *property; + POPValueType valueType; + NSUInteger valueCount; + VectorRef fromVec; + VectorRef toVec; + VectorRef currentVec; + VectorRef previousVec; + VectorRef previous2Vec; + VectorRef velocityVec; + VectorRef originalVelocityVec; + VectorRef distanceVec; + CGFloat roundingFactor; + NSUInteger clampMode; + NSArray *progressMarkers; + POPProgressMarker *progressMarkerState; + NSUInteger progressMarkerCount; + NSUInteger nextProgressMarkerIdx; + CGFloat dynamicsThreshold; + + _POPPropertyAnimationState(id __unsafe_unretained anim) : _POPAnimationState(anim), + property(nil), + valueType((POPValueType)0), + valueCount(0), + fromVec(nullptr), + toVec(nullptr), + currentVec(nullptr), + previousVec(nullptr), + previous2Vec(nullptr), + velocityVec(nullptr), + originalVelocityVec(nullptr), + distanceVec(nullptr), + roundingFactor(0), + clampMode(0), + progressMarkers(nil), + progressMarkerState(nil), + progressMarkerCount(0), + nextProgressMarkerIdx(0), + dynamicsThreshold(0) + { + type = kPOPAnimationBasic; + } + + ~_POPPropertyAnimationState() + { + if (progressMarkerState) { + free(progressMarkerState); + progressMarkerState = NULL; + } + } + + bool canProgress() { + return hasValue(); + } + + bool shouldRound() { + return 0 != roundingFactor; + } + + bool hasValue() { + return 0 != valueCount; + } + + bool isDone() { + // inherit done + if (_POPAnimationState::isDone()) { + return true; + } + + // consider an animation with no values done + if (!hasValue() && !isCustom()) { + return true; + } + + return false; + } + + // returns a copy of the currentVec, rounding if needed + VectorRef currentValue() { + VectorRef vec = VectorRef(Vector::new_vector(currentVec.get())); + if (shouldRound()) { + vec->subRound(1 / roundingFactor); + } + return vec; + } + + void resetProgressMarkerState() + { + for (NSUInteger idx = 0; idx < progressMarkerCount; idx++) + progressMarkerState[idx].reached = false; + + nextProgressMarkerIdx = 0; + } + + void updatedProgressMarkers() + { + if (progressMarkerState) { + free(progressMarkerState); + progressMarkerState = NULL; + } + + progressMarkerCount = progressMarkers.count; + + if (0 != progressMarkerCount) { + progressMarkerState = (POPProgressMarker *)malloc(progressMarkerCount * sizeof(POPProgressMarker)); + [progressMarkers enumerateObjectsUsingBlock:^(NSNumber *progressMarker, NSUInteger idx, BOOL *stop) { + progressMarkerState[idx].reached = false; + progressMarkerState[idx].progress = [progressMarker floatValue]; + }]; + } + + nextProgressMarkerIdx = 0; + } + + virtual void updatedDynamicsThreshold() + { + dynamicsThreshold = property.threshold; + } + + void finalizeProgress() + { + progress = 1.0; + NSUInteger count = valueCount; + VectorRef outVec(Vector::new_vector(count, NULL)); + + if (outVec && toVec) { + *outVec = *toVec; + } + + currentVec = outVec; + clampCurrentValue(); + delegateProgress(); + } + + void computeProgress() { + if (!canProgress()) { + return; + } + + static ComputeProgressFunctor func; + Vector4r v = vector4(currentVec); + Vector4r f = vector4(fromVec); + Vector4r t = vector4(toVec); + progress = func(v, f, t); + } + + void delegateProgress() { + if (!canProgress()) { + return; + } + + if (delegateDidProgress && progressMarkerState) { + + while (nextProgressMarkerIdx < progressMarkerCount) { + if (progress < progressMarkerState[nextProgressMarkerIdx].progress) + break; + + if (!progressMarkerState[nextProgressMarkerIdx].reached) { + ActionEnabler enabler; + [delegate pop_animation:self didReachProgress:progressMarkerState[nextProgressMarkerIdx].progress]; + progressMarkerState[nextProgressMarkerIdx].reached = true; + } + + nextProgressMarkerIdx++; + } + } + + if (!didReachToValue) { + bool didReachToValue = false; + if (0 == valueCount) { + didReachToValue = true; + } else { + Vector4r distance = toVec->vector4r(); + distance -= currentVec->vector4r(); + + if (0 == distance.squaredNorm()) { + didReachToValue = true; + } else { + // components + if (distanceVec) { + didReachToValue = true; + const CGFloat *distanceValues = distanceVec->data(); + for (NSUInteger idx = 0; idx < valueCount; idx++) { + didReachToValue &= (signbit(distance[idx]) != signbit(distanceValues[idx])); + } + } + } + } + + if (didReachToValue) { + handleDidReachToValue(); + } + } + } + + void handleDidReachToValue() { + didReachToValue = true; + + if (delegateDidReachToValue) { + ActionEnabler enabler; + [delegate pop_animationDidReachToValue:self]; + } + + if (tracing) { + [tracer didReachToValue:POPBox(currentValue(), valueType, true)]; + } + } + + void readObjectValue(VectorRef *ptrVec, id obj) + { + // use current object value as from value + pop_animatable_read_block read = property.readBlock; + if (NULL != read) { + + Vector4r vec = read_values(read, obj, valueCount); + *ptrVec = VectorRef(Vector::new_vector(valueCount, vec)); + + if (tracing) { + [tracer readPropertyValue:POPBox(*ptrVec, valueType, true)]; + } + } + } + + virtual void willRun(bool started, id obj) { + // ensure from value initialized + if (NULL == fromVec) { + readObjectValue(&fromVec, obj); + } + + // ensure to value initialized + if (NULL == toVec) { + // compute decay to value + if (kPOPAnimationDecay == type) { + [self toValue]; + } else { + // read to value + readObjectValue(&toVec, obj); + } + } + + // handle one time value initialization on start + if (started) { + + // initialize current vec + if (!currentVec) { + currentVec = VectorRef(Vector::new_vector(valueCount, NULL)); + + // initialize current value with from value + // only do this on initial creation to avoid overwriting current value + // on paused animation continuation + if (currentVec && fromVec) { + *currentVec = *fromVec; + } + } + + // ensure velocity values + if (!velocityVec) { + velocityVec = VectorRef(Vector::new_vector(valueCount, NULL)); + } + if (!originalVelocityVec) { + originalVelocityVec = VectorRef(Vector::new_vector(valueCount, NULL)); + } + } + + // ensure distance value initialized + // depends on current value set on one time start + if (NULL == distanceVec) { + + // not yet started animations may not have current value + VectorRef fromVec2 = NULL != currentVec ? currentVec : fromVec; + + if (fromVec2 && toVec) { + Vector4r distance = toVec->vector4r(); + distance -= fromVec2->vector4r(); + + if (0 != distance.squaredNorm()) { + distanceVec = VectorRef(Vector::new_vector(valueCount, distance)); + } + } + } + } + + virtual void reset(bool all) { + _POPAnimationState::reset(all); + + if (all) { + currentVec = NULL; + previousVec = NULL; + previous2Vec = NULL; + } + progress = 0; + resetProgressMarkerState(); + didReachToValue = false; + distanceVec = NULL; + } + + void clampCurrentValue(NSUInteger clamp) + { + if (kPOPAnimationClampNone == clamp) + return; + + // Clamp all vector values + CGFloat *currentValues = currentVec->data(); + const CGFloat *fromValues = fromVec->data(); + const CGFloat *toValues = toVec->data(); + + for (NSUInteger idx = 0; idx < valueCount; idx++) { + clampValue(currentValues[idx], fromValues[idx], toValues[idx], clamp); + } + } + + void clampCurrentValue() + { + clampCurrentValue(clampMode); + } +}; + +typedef struct _POPPropertyAnimationState POPPropertyAnimationState; + +@interface POPPropertyAnimation () + +@end + diff --git a/Example/Pods/pop/pop/POPSpringAnimation.h b/Example/Pods/pop/pop/POPSpringAnimation.h new file mode 100644 index 0000000..60916d4 --- /dev/null +++ b/Example/Pods/pop/pop/POPSpringAnimation.h @@ -0,0 +1,67 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#import + +/** + @abstract A concrete spring animation class. + @discussion Animation is achieved through modeling spring dynamics. + */ +@interface POPSpringAnimation : POPPropertyAnimation + +/** + @abstract The designated initializer. + @returns An instance of a spring animation. + */ ++ (instancetype)animation; + +/** + @abstract Convenience initializer that returns an animation with animatable property of name. + @param name The name of the animatable property. + @returns An instance of a spring animation configured with specified animatable property. + */ ++ (instancetype)animationWithPropertyNamed:(NSString *)name; + +/** + @abstract The current velocity value. + @discussion Set before animation start to account for initial velocity. Expressed in change of value units per second. + */ +@property (copy, nonatomic) id velocity; + +/** + @abstract The effective bounciness. + @discussion Use in conjunction with 'springSpeed' to change animation effect. Values are converted into corresponding dynamics constants. Defined as a value in the range [0, 20]. Defaults to 4. + */ +@property (assign, nonatomic) CGFloat springBounciness; + +/** + @abstract The effective speed. + @discussion Use in conjunction with 'springBounciness' to change animation effect. Values are converted into corresponding dynamics constants. Defined as a value in the range [0, 20]. Defaults to 12. + */ +@property (assign, nonatomic) CGFloat springSpeed; + +/** + @abstract The tension used in the dynamics simulation. + @discussion Can be used over bounciness and speed for finer grain tweaking of animation effect. + */ +@property (assign, nonatomic) CGFloat dynamicsTension; + +/** + @abstract The friction used in the dynamics simulation. + @discussion Can be used over bounciness and speed for finer grain tweaking of animation effect. + */ +@property (assign, nonatomic) CGFloat dynamicsFriction; + +/** + @abstract The mass used in the dynamics simulation. + @discussion Can be used over bounciness and speed for finer grain tweaking of animation effect. + */ +@property (assign, nonatomic) CGFloat dynamicsMass; + +@end diff --git a/Example/Pods/pop/pop/POPSpringAnimation.mm b/Example/Pods/pop/pop/POPSpringAnimation.mm new file mode 100644 index 0000000..10cb510 --- /dev/null +++ b/Example/Pods/pop/pop/POPSpringAnimation.mm @@ -0,0 +1,164 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#import "POPSpringAnimationInternal.h" + +@implementation POPSpringAnimation + +#pragma mark - Lifecycle + +#undef __state +#define __state ((POPSpringAnimationState *)_state) + ++ (instancetype)animation +{ + return [[self alloc] init]; +} + ++ (instancetype)animationWithPropertyNamed:(NSString *)aName +{ + POPSpringAnimation *anim = [self animation]; + anim.property = [POPAnimatableProperty propertyWithName:aName]; + return anim; +} + +- (void)_initState +{ + _state = new POPSpringAnimationState(self); +} + +- (id)init +{ + self = [super _init]; + if (nil != self) { + __state->solver = new SpringSolver4d(1, 1, 1); + __state->updatedDynamicsThreshold(); + __state->updatedBouncinessAndSpeed(); + } + return self; +} + +- (void)dealloc +{ + if (__state) { + delete __state->solver; + __state->solver = NULL; + } +} + +#pragma mark - Properties + +- (id)velocity +{ + return POPBox(__state->velocityVec, __state->valueType); +} + +- (void)setVelocity:(id)aValue +{ + POPPropertyAnimationState *s = __state; + VectorRef vec = POPUnbox(aValue, s->valueType, s->valueCount, YES); + if (!vec_equal(vec, s->velocityVec)) { + s->velocityVec = vec; + + if (s->tracing) { + [s->tracer updateVelocity:aValue]; + } + } +} + +DEFINE_RW_PROPERTY(POPSpringAnimationState, dynamicsTension, setDynamicsTension:, CGFloat, [self _updatedDynamicsTension];); +DEFINE_RW_PROPERTY(POPSpringAnimationState, dynamicsFriction, setDynamicsFriction:, CGFloat, [self _updatedDynamicsFriction];); +DEFINE_RW_PROPERTY(POPSpringAnimationState, dynamicsMass, setDynamicsMass:, CGFloat, [self _updatedDynamicsMass];); + +FB_PROPERTY_GET(POPSpringAnimationState, springSpeed, CGFloat); +- (void)setSpringSpeed:(CGFloat)aFloat +{ + POPSpringAnimationState *s = __state; + if (s->userSpecifiedDynamics || aFloat != s->springSpeed) { + s->springSpeed = aFloat; + s->userSpecifiedDynamics = false; + s->updatedBouncinessAndSpeed(); + if (s->tracing) { + [s->tracer updateSpeed:aFloat]; + } + } +} + +FB_PROPERTY_GET(POPSpringAnimationState, springBounciness, CGFloat); +- (void)setSpringBounciness:(CGFloat)aFloat +{ + POPSpringAnimationState *s = __state; + if (s->userSpecifiedDynamics || aFloat != s->springBounciness) { + s->springBounciness = aFloat; + s->userSpecifiedDynamics = false; + s->updatedBouncinessAndSpeed(); + if (s->tracing) { + [s->tracer updateBounciness:aFloat]; + } + } +} + +- (SpringSolver4d *)solver +{ + return __state->solver; +} + +- (void)setSolver:(SpringSolver4d *)aSolver +{ + if (aSolver != __state->solver) { + if (__state->solver) { + delete(__state->solver); + } + __state->solver = aSolver; + } +} + +#pragma mark - Utility + +- (void)_updatedDynamicsTension +{ + __state->userSpecifiedDynamics = true; + if(__state->tracing) { + [__state->tracer updateTension:__state->dynamicsTension]; + } + __state->updatedDynamics(); +} + +- (void)_updatedDynamicsFriction +{ + __state->userSpecifiedDynamics = true; + if(__state->tracing) { + [__state->tracer updateFriction:__state->dynamicsFriction]; + } + __state->updatedDynamics(); +} + +- (void)_updatedDynamicsMass +{ + __state->userSpecifiedDynamics = true; + if(__state->tracing) { + [__state->tracer updateMass:__state->dynamicsMass]; + } + __state->updatedDynamics(); +} + +- (void)_appendDescription:(NSMutableString *)s debug:(BOOL)debug +{ + [super _appendDescription:s debug:debug]; + + if (debug) { + if (_state->userSpecifiedDynamics) { + [s appendFormat:@"; dynamics = (tension:%f, friction:%f, mass:%f)", __state->dynamicsTension, __state->dynamicsFriction, __state->dynamicsMass]; + } else { + [s appendFormat:@"; bounciness = %f; speed = %f", __state->springBounciness, __state->springSpeed]; + } + } +} + +@end diff --git a/Example/Pods/pop/pop/POPSpringAnimationInternal.h b/Example/Pods/pop/pop/POPSpringAnimationInternal.h new file mode 100644 index 0000000..6d17c3c --- /dev/null +++ b/Example/Pods/pop/pop/POPSpringAnimationInternal.h @@ -0,0 +1,130 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#import "POPAnimationExtras.h" +#import "POPPropertyAnimationInternal.h" + +struct _POPSpringAnimationState : _POPPropertyAnimationState +{ + SpringSolver4d *solver; + CGFloat springSpeed; + CGFloat springBounciness; // normalized springiness + CGFloat dynamicsTension; // tension + CGFloat dynamicsFriction; // friction + CGFloat dynamicsMass; // mass + + _POPSpringAnimationState(id __unsafe_unretained anim) : _POPPropertyAnimationState(anim), + solver(nullptr), + springSpeed(12.), + springBounciness(4.), + dynamicsTension(0), + dynamicsFriction(0), + dynamicsMass(0) + { + type = kPOPAnimationSpring; + } + + bool hasConverged() + { + NSUInteger count = valueCount; + if (shouldRound()) { + return vec_equal(previous2Vec, previousVec) && vec_equal(previousVec, toVec); + } else { + if (!previousVec || !previous2Vec) + return false; + + CGFloat t = dynamicsThreshold / 5; + + const CGFloat *toValues = toVec->data(); + const CGFloat *previousValues = previousVec->data(); + const CGFloat *previous2Values = previous2Vec->data(); + + for (NSUInteger idx = 0; idx < count; idx++) { + if ((fabsf(toValues[idx] - previousValues[idx]) >= t) || (fabsf(previous2Values[idx] - previousValues[idx]) >= t)) { + return false; + } + } + return true; + } + } + + bool isDone() { + if (_POPPropertyAnimationState::isDone()) { + return true; + } + return solver->started() && (hasConverged() || solver->hasConverged()); + } + + void updatedDynamics() + { + if (NULL != solver) { + solver->setConstants(dynamicsTension, dynamicsFriction, dynamicsMass); + } + } + + void updatedDynamicsThreshold() + { + _POPPropertyAnimationState::updatedDynamicsThreshold(); + if (NULL != solver) { + solver->setThreshold(dynamicsThreshold); + } + } + + void updatedBouncinessAndSpeed() { + [POPSpringAnimation convertBounciness:springBounciness speed:springSpeed toTension:&dynamicsTension friction:&dynamicsFriction mass:&dynamicsMass]; + updatedDynamics(); + } + + bool advance(CFTimeInterval time, CFTimeInterval dt, id obj) { + // advance past not yet initialized animations + if (NULL == currentVec) { + return false; + } + + CFTimeInterval localTime = time - startTime; + + Vector4d value = vector4d(currentVec); + Vector4d toValue = vector4d(toVec); + Vector4d velocity = vector4d(velocityVec); + + SSState4d state; + state.p = toValue - value; + + // the solver assumes a spring of size zero + // flip the velocity from user perspective to solver perspective + state.v = velocity * -1; + + solver->advance(state, localTime, dt); + value = toValue - state.p; + + // flip velocity back to user perspective + velocity = state.v * -1; + + *currentVec = value; + + if (velocityVec) { + *velocityVec = velocity; + } + + clampCurrentValue(); + + return true; + } + + virtual void reset(bool all) { + _POPPropertyAnimationState::reset(all); + + if (solver) { + solver->setConstants(dynamicsTension, dynamicsFriction, dynamicsMass); + solver->reset(); + } + } +}; + +typedef struct _POPSpringAnimationState POPSpringAnimationState; diff --git a/Example/Pods/pop/pop/POPSpringSolver.h b/Example/Pods/pop/pop/POPSpringSolver.h new file mode 100644 index 0000000..df485bf --- /dev/null +++ b/Example/Pods/pop/pop/POPSpringSolver.h @@ -0,0 +1,190 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#import + +#import "POPVector.h" + +namespace POP { + + template + struct SSState + { + T p; + T v; + }; + + template + struct SSDerivative + { + T dp; + T dv; + }; + + typedef SSState SSState4d; + typedef SSDerivative SSDerivative4d; + + const CFTimeInterval solverDt = 0.001f; + const CFTimeInterval maxSolverDt = 30.0f; + + /** + Templated spring solver class. + */ + template + class SpringSolver + { + double _k; // stiffness + double _b; // dampening + double _m; // mass + + double _tp; // threshold + double _tv; // threshold velocity + double _ta; // threshold acceleration + + CFTimeInterval _accumulatedTime; + SSState _lastState; + T _lastDv; + bool _started; + + public: + SpringSolver(double k, double b, double m = 1) : _k(k), _b(b), _m(m), _started(false) + { + _accumulatedTime = 0; + _lastState.p = T::Zero(); + _lastState.v = T::Zero(); + _lastDv = T::Zero(); + setThreshold(1.); + } + + ~SpringSolver() + { + } + + bool started() + { + return _started; + } + + void setConstants(double k, double b, double m) + { + _k = k; + _b = b; + _m = m; + } + + void setThreshold(double t) + { + _tp = t / 2; // half a unit + _tv = 25.0 * t; // 5 units per second, squared for comparison + _ta = 625.0 * t * t; // 5 units per second squared, squared for comparison + } + + T acceleration(const SSState &state, double t) + { + return state.p*(-_k/_m) - state.v*(_b/_m); + } + + SSDerivative evaluate(const SSState &initial, double t) + { + SSDerivative output; + output.dp = initial.v; + output.dv = acceleration(initial, t); + return output; + } + + SSDerivative evaluate(const SSState &initial, double t, double dt, const SSDerivative &d) + { + SSState state; + state.p = initial.p + d.dp*dt; + state.v = initial.v + d.dv*dt; + SSDerivative output; + output.dp = state.v; + output.dv = acceleration(state, t+dt); + return output; + } + + void integrate(SSState &state, double t, double dt) + { + SSDerivative a = evaluate(state, t); + SSDerivative b = evaluate(state, t, dt*0.5, a); + SSDerivative c = evaluate(state, t, dt*0.5, b); + SSDerivative d = evaluate(state, t, dt, c); + + T dpdt = (a.dp + (b.dp + c.dp)*2.0 + d.dp) * (1.0/6.0); + T dvdt = (a.dv + (b.dv + c.dv)*2.0 + d.dv) * (1.0/6.0); + + state.p = state.p + dpdt*dt; + state.v = state.v + dvdt*dt; + + _lastDv = dvdt; + } + + SSState interpolate(const SSState &previous, const SSState ¤t, double alpha) + { + SSState state; + state.p = current.p*alpha + previous.p*(1-alpha); + state.v = current.v*alpha + previous.v*(1-alpha); + return state; + } + + void advance(SSState &state, double t, double dt) + { + _started = true; + + if (dt > maxSolverDt) { + // excessive time step, force shut down + _lastDv = _lastState.v = _lastState.p = T::Zero(); + } else { + _accumulatedTime += dt; + + SSState previousState = state, currentState = state; + while (_accumulatedTime >= solverDt) { + previousState = currentState; + this->integrate(currentState, t, solverDt); + t += solverDt; + _accumulatedTime -= solverDt; + } + CFTimeInterval alpha = _accumulatedTime / solverDt; + _lastState = state = this->interpolate(previousState, currentState, alpha); + } + } + + bool hasConverged() + { + if (!_started) { + return false; + } + + for (size_t idx = 0; idx < _lastState.p.size(); idx++) { + if (fabs(_lastState.p(idx)) >= _tp) { + return false; + } + } + + return (_lastState.v.squaredNorm() < _tv) && (_lastDv.squaredNorm() < _ta); + } + + void reset() + { + _accumulatedTime = 0; + _lastState.p = T::Zero(); + _lastState.v = T::Zero(); + _lastDv = T::Zero(); + _started = false; + } + }; + + /** + Convenience spring solver type definitions. + */ + typedef SpringSolver SpringSolver2d; + typedef SpringSolver SpringSolver3d; + typedef SpringSolver SpringSolver4d; +} + diff --git a/Example/Pods/pop/pop/POPVector.h b/Example/Pods/pop/pop/POPVector.h new file mode 100644 index 0000000..12db46b --- /dev/null +++ b/Example/Pods/pop/pop/POPVector.h @@ -0,0 +1,375 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#ifndef __POP__FBVector__ +#define __POP__FBVector__ + +#include +#include + +#import +#import +#if TARGET_OS_IPHONE +#import +#endif +#import "POPMath.h" + +namespace POP { + + /** Fixed two-size vector class */ + template + struct Vector2 + { + private: + typedef T Vector2::* const _data[2]; + static const _data _v; + + public: + T x; + T y; + + // Zero vector + static const Vector2 Zero() { return Vector2(0); } + + // Constructors + Vector2() {} + explicit Vector2(T v) { x = v; y = v; }; + explicit Vector2(T x0, T y0) : x(x0), y(y0) {}; + explicit Vector2(const CGPoint &p) : x(p.x), y (p.y) {} + explicit Vector2(const CGSize &s) : x(s.width), y (s.height) {} + + // Copy constructor + template explicit Vector2(const Vector2 &v) : x(v.x), y(v.y) {} + + // Index operators + const T& operator[](size_t i) const { return this->*_v[i]; } + T& operator[](size_t i) { return this->*_v[i]; } + const T& operator()(size_t i) const { return this->*_v[i]; } + T& operator()(size_t i) { return this->*_v[i]; } + + // Backing data + T * data() { return &(this->*_v[0]); } + const T * data() const { return &(this->*_v[0]); } + + // Size + inline size_t size() const { return 2; } + + // Assignment + Vector2 &operator= (T v) { x = v; y = v; return *this;} + template Vector2 &operator= (const Vector2 &v) { x = v.x; y = v.y; return *this;} + + // Negation + Vector2 operator- (void) const { return Vector2(-x, -y); } + + // Equality + bool operator== (T v) const { return (x == v && y == v); } + bool operator== (const Vector2 &v) const { return (x == v.x && y == v.y); } + + // Inequality + bool operator!= (T v) const {return (x != v || y != v); } + bool operator!= (const Vector2 &v) const { return (x != v.x || y != v.y); } + + // Scalar Math + Vector2 operator+ (T v) const { return Vector2(x + v, y + v); } + Vector2 operator- (T v) const { return Vector2(x - v, y - v); } + Vector2 operator* (T v) const { return Vector2(x * v, y * v); } + Vector2 operator/ (T v) const { return Vector2(x / v, y / v); } + Vector2 &operator+= (T v) { x += v; y += v; return *this; }; + Vector2 &operator-= (T v) { x -= v; y -= v; return *this; }; + Vector2 &operator*= (T v) { x *= v; y *= v; return *this; }; + Vector2 &operator/= (T v) { x /= v; y /= v; return *this; }; + + // Vector Math + Vector2 operator+ (const Vector2 &v) const { return Vector2(x + v.x, y + v.y); } + Vector2 operator- (const Vector2 &v) const { return Vector2(x - v.x, y - v.y); } + Vector2 &operator+= (const Vector2 &v) { x += v.x; y += v.y; return *this; }; + Vector2 &operator-= (const Vector2 &v) { x -= v.x; y -= v.y; return *this; }; + + // Norms + CGFloat norm() const { return sqrtr(squaredNorm()); } + CGFloat squaredNorm() const { return x * x + y * y; } + + // Cast + template Vector2 cast() const { return Vector2(x, y); } + CGPoint cg_point() const { return CGPointMake(x, y); }; + }; + + template + const typename Vector2::_data Vector2::_v = { &Vector2::x, &Vector2::y }; + + /** Fixed three-size vector class */ + template + struct Vector3 + { + private: + typedef T Vector3::* const _data[3]; + static const _data _v; + + public: + T x; + T y; + T z; + + // Zero vector + static const Vector3 Zero() { return Vector3(0); }; + + // Constructors + Vector3() {} + explicit Vector3(T v) : x(v), y(v), z(v) {}; + explicit Vector3(T x0, T y0, T z0) : x(x0), y(y0), z(z0) {}; + + // Copy constructor + template explicit Vector3(const Vector3 &v) : x(v.x), y(v.y), z(v.z) {} + + // Index operators + const T& operator[](size_t i) const { return this->*_v[i]; } + T& operator[](size_t i) { return this->*_v[i]; } + const T& operator()(size_t i) const { return this->*_v[i]; } + T& operator()(size_t i) { return this->*_v[i]; } + + // Backing data + T * data() { return &(this->*_v[0]); } + const T * data() const { return &(this->*_v[0]); } + + // Size + inline size_t size() const { return 3; } + + // Assignment + Vector3 &operator= (T v) { x = v; y = v; z = v; return *this;} + template Vector3 &operator= (const Vector3 &v) { x = v.x; y = v.y; z = v.z; return *this;} + + // Negation + Vector3 operator- (void) const { return Vector3(-x, -y, -z); } + + // Equality + bool operator== (T v) const { return (x == v && y == v && z = v); } + bool operator== (const Vector3 &v) const { return (x == v.x && y == v.y && z == v.z); } + + // Inequality + bool operator!= (T v) const {return (x != v || y != v || z != v); } + bool operator!= (const Vector3 &v) const { return (x != v.x || y != v.y || z != v.z); } + + // Scalar Math + Vector3 operator+ (T v) const { return Vector3(x + v, y + v, z + v); } + Vector3 operator- (T v) const { return Vector3(x - v, y - v, z - v); } + Vector3 operator* (T v) const { return Vector3(x * v, y * v, z * v); } + Vector3 operator/ (T v) const { return Vector3(x / v, y / v, z / v); } + Vector3 &operator+= (T v) { x += v; y += v; z += v; return *this; }; + Vector3 &operator-= (T v) { x -= v; y -= v; z -= v; return *this; }; + Vector3 &operator*= (T v) { x *= v; y *= v; z *= v; return *this; }; + Vector3 &operator/= (T v) { x /= v; y /= v; z /= v; return *this; }; + + // Vector Math + Vector3 operator+ (const Vector3 &v) const { return Vector3(x + v.x, y + v.y, z + v.z); } + Vector3 operator- (const Vector3 &v) const { return Vector3(x - v.x, y - v.y, z - v.z); } + Vector3 &operator+= (const Vector3 &v) { x += v.x; y += v.y; z += v.z; return *this; }; + Vector3 &operator-= (const Vector3 &v) { x -= v.x; y -= v.y; z -= v.z; return *this; }; + + // Norms + CGFloat norm() const { return sqrtr(squaredNorm()); } + CGFloat squaredNorm() const { return x * x + y * y + z * z; } + + // Cast + template Vector3 cast() const { return Vector3(x, y, z); } + }; + + template + const typename Vector3::_data Vector3::_v = { &Vector3::x, &Vector3::y, &Vector3::z }; + + /** Fixed four-size vector class */ + template + struct Vector4 + { + private: + typedef T Vector4::* const _data[4]; + static const _data _v; + + public: + T x; + T y; + T z; + T w; + + // Zero vector + static const Vector4 Zero() { return Vector4(0); }; + + // Constructors + Vector4() {} + explicit Vector4(T v) : x(v), y(v), z(v), w(v) {}; + explicit Vector4(T x0, T y0, T z0, T w0) : x(x0), y(y0), z(z0), w(w0) {}; + + // Copy constructor + template explicit Vector4(const Vector4 &v) : x(v.x), y(v.y), z(v.z), w(v.w) {} + + // Index operators + const T& operator[](size_t i) const { return this->*_v[i]; } + T& operator[](size_t i) { return this->*_v[i]; } + const T& operator()(size_t i) const { return this->*_v[i]; } + T& operator()(size_t i) { return this->*_v[i]; } + + // Backing data + T * data() { return &(this->*_v[0]); } + const T * data() const { return &(this->*_v[0]); } + + // Size + inline size_t size() const { return 4; } + + // Assignment + Vector4 &operator= (T v) { x = v; y = v; z = v; w = v; return *this;} + template Vector4 &operator= (const Vector4 &v) { x = v.x; y = v.y; z = v.z; w = v.w; return *this;} + + // Negation + Vector4 operator- (void) const { return Vector4(-x, -y, -z, -w); } + + // Equality + bool operator== (T v) const { return (x == v && y == v && z = v, w = v); } + bool operator== (const Vector4 &v) const { return (x == v.x && y == v.y && z == v.z && w == v.w); } + + // Inequality + bool operator!= (T v) const {return (x != v || y != v || z != v || w != v); } + bool operator!= (const Vector4 &v) const { return (x != v.x || y != v.y || z != v.z || w != v.w); } + + // Scalar Math + Vector4 operator+ (T v) const { return Vector4(x + v, y + v, z + v, w + v); } + Vector4 operator- (T v) const { return Vector4(x - v, y - v, z - v, w - v); } + Vector4 operator* (T v) const { return Vector4(x * v, y * v, z * v, w * v); } + Vector4 operator/ (T v) const { return Vector4(x / v, y / v, z / v, w / v); } + Vector4 &operator+= (T v) { x += v; y += v; z += v; w += v; return *this; }; + Vector4 &operator-= (T v) { x -= v; y -= v; z -= v; w -= v; return *this; }; + Vector4 &operator*= (T v) { x *= v; y *= v; z *= v; w *= v; return *this; }; + Vector4 &operator/= (T v) { x /= v; y /= v; z /= v; w /= v; return *this; }; + + // Vector Math + Vector4 operator+ (const Vector4 &v) const { return Vector4(x + v.x, y + v.y, z + v.z, w + v.w); } + Vector4 operator- (const Vector4 &v) const { return Vector4(x - v.x, y - v.y, z - v.z, w - v.w); } + Vector4 &operator+= (const Vector4 &v) { x += v.x; y += v.y; z += v.z; w += v.w; return *this; }; + Vector4 &operator-= (const Vector4 &v) { x -= v.x; y -= v.y; z -= v.z; w -= v.w; return *this; }; + + // Norms + CGFloat norm() const { return sqrtr(squaredNorm()); } + CGFloat squaredNorm() const { return x * x + y * y + z * z + w * w; } + + // Cast + template Vector4 cast() const { return Vector4(x, y, z, w); } + }; + + template + const typename Vector4::_data Vector4::_v = { &Vector4::x, &Vector4::y, &Vector4::z, &Vector4::w }; + + /** Convenience typedefs */ + typedef Vector2 Vector2f; + typedef Vector2 Vector2d; + typedef Vector2 Vector2r; + typedef Vector3 Vector3f; + typedef Vector3 Vector3d; + typedef Vector3 Vector3r; + typedef Vector4 Vector4f; + typedef Vector4 Vector4d; + typedef Vector4 Vector4r; + + /** Variable-sized vector class */ + class Vector + { + size_t _count; + CGFloat *_values; + + private: + Vector(size_t); + Vector(const Vector& other); + + public: + ~Vector(); + + // Creates a new vector instance of count with values. Initializing a vector of size 0 returns NULL. + static Vector *new_vector(NSUInteger count, const CGFloat *values); + + // Creates a new vector given a pointer to another. Can return NULL. + static Vector *new_vector(const Vector * const other); + + // Creates a variable size vector given a static vector and count. + static Vector *new_vector(NSUInteger count, Vector4r vec); + + // Size of vector + NSUInteger size() const { return _count; } + + // Returns array of values + CGFloat *data () { return _values; } + const CGFloat *data () const { return _values; }; + + // Vector2r support + Vector2r vector2r() const; + + // Vector4r support + Vector4r vector4r() const; + + // CGFloat support + static Vector *new_cg_float(CGFloat f); + + // CGPoint support + CGPoint cg_point() const; + static Vector *new_cg_point(const CGPoint &p); + + // CGSize support + CGSize cg_size() const; + static Vector *new_cg_size(const CGSize &s); + + // CGRect support + CGRect cg_rect() const; + static Vector *new_cg_rect(const CGRect &r); + +#if TARGET_OS_IPHONE + // UIEdgeInsets support + UIEdgeInsets ui_edge_insets() const; + static Vector *new_ui_edge_insets(const UIEdgeInsets &i); +#endif + + // CGAffineTransform support + CGAffineTransform cg_affine_transform() const; + static Vector *new_cg_affine_transform(const CGAffineTransform &t); + + // CGColorRef support + CGColorRef cg_color() const CF_RETURNS_RETAINED; + static Vector *new_cg_color(CGColorRef color); + + // operator overloads + CGFloat &operator[](size_t i) const { + NSCAssert(size() > i, @"unexpected vector size:%lu", (unsigned long)size()); + return _values[i]; + } + + // Returns the mathematical length + CGFloat norm() const; + CGFloat squaredNorm() const; + + // Round to nearest sub + void subRound(CGFloat sub); + + // Returns string description + NSString * toString() const; + + // Operator overloads + template Vector& operator= (const Vector4& other) { + size_t count = MIN(_count, other.size()); + for (size_t i = 0; i < count; i++) { + _values[i] = other[i]; + } + return *this; + } + Vector& operator= (const Vector& other); + void swap(Vector &first, Vector &second); + bool operator==(const Vector &other) const; + bool operator!=(const Vector &other) const; + }; + + /** Convenience typedefs */ + typedef std::shared_ptr VectorRef; + typedef std::shared_ptr VectorConstRef; + +} +#endif /* defined(__POP__FBVector__) */ diff --git a/Example/Pods/pop/pop/POPVector.mm b/Example/Pods/pop/pop/POPVector.mm new file mode 100644 index 0000000..b9b6103 --- /dev/null +++ b/Example/Pods/pop/pop/POPVector.mm @@ -0,0 +1,301 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#import "POPVector.h" +#import "POPCGUtils.h" + +namespace POP +{ + + Vector::Vector(const size_t count) + { + _count = count; + _values = 0 != count ? (CGFloat *)calloc(count, sizeof(CGFloat)) : NULL; + } + + Vector::Vector(const Vector& other) + { + _count = other.size(); + _values = 0 != _count ? (CGFloat *)calloc(_count, sizeof(CGFloat)) : NULL; + if (0 != _count) { + memcpy(_values, other.data(), _count * sizeof(CGFloat)); + } + } + + Vector::~Vector() + { + if (NULL != _values) { + free(_values); + _values = NULL; + } + _count = 0; + } + + void Vector::swap(Vector &first, Vector &second) + { + using std::swap; + swap(first._count, second._count); + swap(first._values, second._values); + } + + Vector& Vector::operator=(const Vector& other) + { + Vector temp(other); + swap(*this, temp); + return *this; + } + + bool Vector::operator==(const Vector &other) const { + if (_count != other.size()) { + return false; + } + + const CGFloat * const values = other.data(); + + for (NSUInteger idx = 0; idx < _count; idx++) { + if (_values[idx] != values[idx]) { + return false; + } + } + + return true; + } + + bool Vector::operator!=(const Vector &other) const { + if (_count == other.size()) { + return false; + } + + const CGFloat * const values = other.data(); + + for (NSUInteger idx = 0; idx < _count; idx++) { + if (_values[idx] != values[idx]) { + return false; + } + } + + return true; + } + + Vector *Vector::new_vector(NSUInteger count, const CGFloat *values) + { + if (0 == count) { + return NULL; + } + + Vector *v = new Vector(count); + if (NULL != values) { + memcpy(v->_values, values, count * sizeof(CGFloat)); + } + return v; + } + + Vector *Vector::new_vector(const Vector * const other) + { + if (NULL == other) { + return NULL; + } + + return Vector::new_vector(other->size(), other->data()); + } + + Vector *Vector::new_vector(NSUInteger count, Vector4r vec) + { + if (0 == count) { + return NULL; + } + + Vector *v = new Vector(count); + + NSCAssert(count <= 4, @"unexpected count %lu", (unsigned long)count); + for (NSUInteger i = 0; i < MIN(count, (NSUInteger)4); i++) { + v->_values[i] = vec[i]; + } + + return v; + } + + Vector4r Vector::vector4r() const + { + Vector4r v = Vector4r::Zero(); + for (size_t i = 0; i < _count; i++) { + v(i) = _values[i]; + } + return v; + } + + Vector2r Vector::vector2r() const + { + Vector2r v = Vector2r::Zero(); + if (_count > 0) v(0) = _values[0]; + if (_count > 1) v(1) = _values[1]; + return v; + } + + Vector *Vector::new_cg_float(CGFloat f) + { + Vector *v = new Vector(1); + v->_values[0] = f; + return v; + } + + CGPoint Vector::cg_point () const + { + Vector2r v = vector2r(); + return CGPointMake(v(0), v(1)); + } + + Vector *Vector::new_cg_point(const CGPoint &p) + { + Vector *v = new Vector(2); + v->_values[0] = p.x; + v->_values[1] = p.y; + return v; + } + + CGSize Vector::cg_size () const + { + Vector2r v = vector2r(); + return CGSizeMake(v(0), v(1)); + } + + Vector *Vector::new_cg_size(const CGSize &s) + { + Vector *v = new Vector(2); + v->_values[0] = s.width; + v->_values[1] = s.height; + return v; + } + + CGRect Vector::cg_rect() const + { + return _count < 4 ? CGRectZero : CGRectMake(_values[0], _values[1], _values[2], _values[3]); + } + + Vector *Vector::new_cg_rect(const CGRect &r) + { + Vector *v = new Vector(4); + v->_values[0] = r.origin.x; + v->_values[1] = r.origin.y; + v->_values[2] = r.size.width; + v->_values[3] = r.size.height; + return v; + } + +#if TARGET_OS_IPHONE + + UIEdgeInsets Vector::ui_edge_insets() const + { + return _count < 4 ? UIEdgeInsetsZero : UIEdgeInsetsMake(_values[0], _values[1], _values[2], _values[3]); + } + + Vector *Vector::new_ui_edge_insets(const UIEdgeInsets &i) + { + Vector *v = new Vector(4); + v->_values[0] = i.top; + v->_values[1] = i.left; + v->_values[2] = i.bottom; + v->_values[3] = i.right; + return v; + } + +#endif + + CGAffineTransform Vector::cg_affine_transform() const + { + if (_count < 6) { + return CGAffineTransformIdentity; + } + + NSCAssert(size() >= 6, @"unexpected vector size:%lu", (unsigned long)size()); + CGAffineTransform t; + t.a = _values[0]; + t.b = _values[1]; + t.c = _values[2]; + t.d = _values[3]; + t.tx = _values[4]; + t.ty = _values[5]; + return t; + } + + Vector *Vector::new_cg_affine_transform(const CGAffineTransform &t) + { + Vector *v = new Vector(6); + v->_values[0] = t.a; + v->_values[1] = t.b; + v->_values[2] = t.c; + v->_values[3] = t.d; + v->_values[4] = t.tx; + v->_values[5] = t.ty; + return v; + } + + CGColorRef Vector::cg_color() const + { + if (_count < 4) { + return NULL; + } + return POPCGColorRGBACreate(_values); + } + + Vector *Vector::new_cg_color(CGColorRef color) + { + CGFloat rgba[4]; + POPCGColorGetRGBAComponents(color, rgba); + return new_vector(4, rgba); + } + + void Vector::subRound(CGFloat sub) + { + for (NSUInteger idx = 0; idx < _count; idx++) { + _values[idx] = POPSubRound(_values[idx], sub); + } + } + + CGFloat Vector::norm() const + { + return sqrtr(squaredNorm()); + } + + CGFloat Vector::squaredNorm() const + { + CGFloat d = 0; + for (NSUInteger idx = 0; idx < _count; idx++) { + d += (_values[idx] * _values[idx]); + } + return d; + } + + NSString * Vector::toString() const + { + if (0 == _count) + return @"()"; + + if (1 == _count) + return [NSString stringWithFormat:@"%f", _values[0]]; + + if (2 == _count) + return [NSString stringWithFormat:@"(%.3f, %.3f)", _values[0], _values[1]]; + + NSMutableString *s = [NSMutableString stringWithCapacity:10]; + + for (NSUInteger idx = 0; idx < _count; idx++) { + if (0 == idx) { + [s appendFormat:@"[%.3f", _values[idx]]; + } else if (idx == _count - 1) { + [s appendFormat:@", %.3f]", _values[idx]]; + } else { + [s appendFormat:@", %.3f", _values[idx]]; + } + } + + return s; + + } +} diff --git a/Example/Pods/pop/pop/WebCore/FloatConversion.h b/Example/Pods/pop/pop/WebCore/FloatConversion.h new file mode 100644 index 0000000..4a16166 --- /dev/null +++ b/Example/Pods/pop/pop/WebCore/FloatConversion.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2007 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef FloatConversion_h +#define FloatConversion_h + +#include + +namespace WebCore { + + template + float narrowPrecisionToFloat(T); + + template<> + inline float narrowPrecisionToFloat(double number) + { + return static_cast(number); + } + + template + CGFloat narrowPrecisionToCGFloat(T); + + template<> + inline CGFloat narrowPrecisionToCGFloat(double number) + { + return static_cast(number); + } + +} // namespace WebCore + +#endif // FloatConversion_h diff --git a/Example/Pods/pop/pop/WebCore/TransformationMatrix.cpp b/Example/Pods/pop/pop/WebCore/TransformationMatrix.cpp new file mode 100644 index 0000000..cbfd701 --- /dev/null +++ b/Example/Pods/pop/pop/WebCore/TransformationMatrix.cpp @@ -0,0 +1,1072 @@ +/* + * Copyright (C) 2005, 2006 Apple Computer, Inc. All rights reserved. + * Copyright (C) 2009 Torch Mobile, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "TransformationMatrix.h" +#include "FloatConversion.h" +#include + +inline double deg2rad(double d) { return d * M_PI / 180.0; } +inline double rad2deg(double r) { return r * 180.0 / M_PI; } +inline double deg2grad(double d) { return d * 400.0 / 360.0; } +inline double grad2deg(double g) { return g * 360.0 / 400.0; } +inline double turn2deg(double t) { return t * 360.0; } +inline double deg2turn(double d) { return d / 360.0; } +inline double rad2grad(double r) { return r * 200.0 / M_PI; } +inline double grad2rad(double g) { return g * M_PI / 200.0; } + +//using namespace std; + +namespace WebCore { + + // + // Supporting Math Functions + // + // This is a set of function from various places (attributed inline) to do things like + // inversion and decomposition of a 4x4 matrix. They are used throughout the code + // + + // + // Adapted from Matrix Inversion by Richard Carling, Graphics Gems . + + // EULA: The Graphics Gems code is copyright-protected. In other words, you cannot claim the text of the code + // as your own and resell it. Using the code is permitted in any program, product, or library, non-commercial + // or commercial. Giving credit is not required, though is a nice gesture. The code comes as-is, and if there + // are any flaws or problems with any Gems code, nobody involved with Gems - authors, editors, publishers, or + // webmasters - are to be held responsible. Basically, don't be a jerk, and remember that anything free comes + // with no guarantee. + + // A clarification about the storage of matrix elements + // + // This class uses a 2 dimensional array internally to store the elements of the matrix. The first index into + // the array refers to the column that the element lies in; the second index refers to the row. + // + // In other words, this is the layout of the matrix: + // + // | m_matrix[0][0] m_matrix[1][0] m_matrix[2][0] m_matrix[3][0] | + // | m_matrix[0][1] m_matrix[1][1] m_matrix[2][1] m_matrix[3][1] | + // | m_matrix[0][2] m_matrix[1][2] m_matrix[2][2] m_matrix[3][2] | + // | m_matrix[0][3] m_matrix[1][3] m_matrix[2][3] m_matrix[3][3] | + + typedef double Vector4[4]; + typedef double Vector3[3]; + + const double SMALL_NUMBER = 1.e-8; + + // inverse(original_matrix, inverse_matrix) + // + // calculate the inverse of a 4x4 matrix + // + // -1 + // A = ___1__ adjoint A + // det A + + // double = determinant2x2(double a, double b, double c, double d) + // + // calculate the determinant of a 2x2 matrix. + + static double determinant2x2(double a, double b, double c, double d) + { + return a * d - b * c; + } + + // double = determinant3x3(a1, a2, a3, b1, b2, b3, c1, c2, c3) + // + // Calculate the determinant of a 3x3 matrix + // in the form + // + // | a1, b1, c1 | + // | a2, b2, c2 | + // | a3, b3, c3 | + + static double determinant3x3(double a1, double a2, double a3, double b1, double b2, double b3, double c1, double c2, double c3) + { + return a1 * determinant2x2(b2, b3, c2, c3) + - b1 * determinant2x2(a2, a3, c2, c3) + + c1 * determinant2x2(a2, a3, b2, b3); + } + + // double = determinant4x4(matrix) + // + // calculate the determinant of a 4x4 matrix. + + static double determinant4x4(const TransformationMatrix::Matrix4& m) + { + // Assign to individual variable names to aid selecting + // correct elements + + double a1 = m[0][0]; + double b1 = m[0][1]; + double c1 = m[0][2]; + double d1 = m[0][3]; + + double a2 = m[1][0]; + double b2 = m[1][1]; + double c2 = m[1][2]; + double d2 = m[1][3]; + + double a3 = m[2][0]; + double b3 = m[2][1]; + double c3 = m[2][2]; + double d3 = m[2][3]; + + double a4 = m[3][0]; + double b4 = m[3][1]; + double c4 = m[3][2]; + double d4 = m[3][3]; + + return a1 * determinant3x3(b2, b3, b4, c2, c3, c4, d2, d3, d4) + - b1 * determinant3x3(a2, a3, a4, c2, c3, c4, d2, d3, d4) + + c1 * determinant3x3(a2, a3, a4, b2, b3, b4, d2, d3, d4) + - d1 * determinant3x3(a2, a3, a4, b2, b3, b4, c2, c3, c4); + } + + // adjoint( original_matrix, inverse_matrix ) + // + // calculate the adjoint of a 4x4 matrix + // + // Let a denote the minor determinant of matrix A obtained by + // ij + // + // deleting the ith row and jth column from A. + // + // i+j + // Let b = (-1) a + // ij ji + // + // The matrix B = (b ) is the adjoint of A + // ij + + static void adjoint(const TransformationMatrix::Matrix4& matrix, TransformationMatrix::Matrix4& result) + { + // Assign to individual variable names to aid + // selecting correct values + double a1 = matrix[0][0]; + double b1 = matrix[0][1]; + double c1 = matrix[0][2]; + double d1 = matrix[0][3]; + + double a2 = matrix[1][0]; + double b2 = matrix[1][1]; + double c2 = matrix[1][2]; + double d2 = matrix[1][3]; + + double a3 = matrix[2][0]; + double b3 = matrix[2][1]; + double c3 = matrix[2][2]; + double d3 = matrix[2][3]; + + double a4 = matrix[3][0]; + double b4 = matrix[3][1]; + double c4 = matrix[3][2]; + double d4 = matrix[3][3]; + + // Row column labeling reversed since we transpose rows & columns + result[0][0] = determinant3x3(b2, b3, b4, c2, c3, c4, d2, d3, d4); + result[1][0] = - determinant3x3(a2, a3, a4, c2, c3, c4, d2, d3, d4); + result[2][0] = determinant3x3(a2, a3, a4, b2, b3, b4, d2, d3, d4); + result[3][0] = - determinant3x3(a2, a3, a4, b2, b3, b4, c2, c3, c4); + + result[0][1] = - determinant3x3(b1, b3, b4, c1, c3, c4, d1, d3, d4); + result[1][1] = determinant3x3(a1, a3, a4, c1, c3, c4, d1, d3, d4); + result[2][1] = - determinant3x3(a1, a3, a4, b1, b3, b4, d1, d3, d4); + result[3][1] = determinant3x3(a1, a3, a4, b1, b3, b4, c1, c3, c4); + + result[0][2] = determinant3x3(b1, b2, b4, c1, c2, c4, d1, d2, d4); + result[1][2] = - determinant3x3(a1, a2, a4, c1, c2, c4, d1, d2, d4); + result[2][2] = determinant3x3(a1, a2, a4, b1, b2, b4, d1, d2, d4); + result[3][2] = - determinant3x3(a1, a2, a4, b1, b2, b4, c1, c2, c4); + + result[0][3] = - determinant3x3(b1, b2, b3, c1, c2, c3, d1, d2, d3); + result[1][3] = determinant3x3(a1, a2, a3, c1, c2, c3, d1, d2, d3); + result[2][3] = - determinant3x3(a1, a2, a3, b1, b2, b3, d1, d2, d3); + result[3][3] = determinant3x3(a1, a2, a3, b1, b2, b3, c1, c2, c3); + } + + // Returns false if the matrix is not invertible + static bool inverse(const TransformationMatrix::Matrix4& matrix, TransformationMatrix::Matrix4& result) + { + // Calculate the adjoint matrix + adjoint(matrix, result); + + // Calculate the 4x4 determinant + // If the determinant is zero, + // then the inverse matrix is not unique. + double det = determinant4x4(matrix); + + if (fabs(det) < SMALL_NUMBER) + return false; + + // Scale the adjoint matrix to get the inverse + + for (int i = 0; i < 4; i++) + for (int j = 0; j < 4; j++) + result[i][j] = result[i][j] / det; + + return true; + } + + // End of code adapted from Matrix Inversion by Richard Carling + + // Perform a decomposition on the passed matrix, return false if unsuccessful + // From Graphics Gems: unmatrix.c + + // Transpose rotation portion of matrix a, return b + static void transposeMatrix4(const TransformationMatrix::Matrix4& a, TransformationMatrix::Matrix4& b) + { + for (int i = 0; i < 4; i++) + for (int j = 0; j < 4; j++) + b[i][j] = a[j][i]; + } + + // Multiply a homogeneous point by a matrix and return the transformed point + static void v4MulPointByMatrix(const Vector4 p, const TransformationMatrix::Matrix4& m, Vector4 result) + { + result[0] = (p[0] * m[0][0]) + (p[1] * m[1][0]) + + (p[2] * m[2][0]) + (p[3] * m[3][0]); + result[1] = (p[0] * m[0][1]) + (p[1] * m[1][1]) + + (p[2] * m[2][1]) + (p[3] * m[3][1]); + result[2] = (p[0] * m[0][2]) + (p[1] * m[1][2]) + + (p[2] * m[2][2]) + (p[3] * m[3][2]); + result[3] = (p[0] * m[0][3]) + (p[1] * m[1][3]) + + (p[2] * m[2][3]) + (p[3] * m[3][3]); + } + + static double v3Length(Vector3 a) + { + return sqrt((a[0] * a[0]) + (a[1] * a[1]) + (a[2] * a[2])); + } + + static void v3Scale(Vector3 v, double desiredLength) + { + double len = v3Length(v); + if (len != 0) { + double l = desiredLength / len; + v[0] *= l; + v[1] *= l; + v[2] *= l; + } + } + + static double v3Dot(const Vector3 a, const Vector3 b) + { + return (a[0] * b[0]) + (a[1] * b[1]) + (a[2] * b[2]); + } + + // Make a linear combination of two vectors and return the result. + // result = (a * ascl) + (b * bscl) + static void v3Combine(const Vector3 a, const Vector3 b, Vector3 result, double ascl, double bscl) + { + result[0] = (ascl * a[0]) + (bscl * b[0]); + result[1] = (ascl * a[1]) + (bscl * b[1]); + result[2] = (ascl * a[2]) + (bscl * b[2]); + } + + // Return the cross product result = a cross b */ + static void v3Cross(const Vector3 a, const Vector3 b, Vector3 result) + { + result[0] = (a[1] * b[2]) - (a[2] * b[1]); + result[1] = (a[2] * b[0]) - (a[0] * b[2]); + result[2] = (a[0] * b[1]) - (a[1] * b[0]); + } + + static bool decompose(const TransformationMatrix::Matrix4& mat, TransformationMatrix::DecomposedType& result) + { + TransformationMatrix::Matrix4 localMatrix; + memcpy(localMatrix, mat, sizeof(TransformationMatrix::Matrix4)); + + // Normalize the matrix. + if (localMatrix[3][3] == 0) + return false; + + int i, j; + for (i = 0; i < 4; i++) + for (j = 0; j < 4; j++) + localMatrix[i][j] /= localMatrix[3][3]; + + // perspectiveMatrix is used to solve for perspective, but it also provides + // an easy way to test for singularity of the upper 3x3 component. + TransformationMatrix::Matrix4 perspectiveMatrix; + memcpy(perspectiveMatrix, localMatrix, sizeof(TransformationMatrix::Matrix4)); + for (i = 0; i < 3; i++) + perspectiveMatrix[i][3] = 0; + perspectiveMatrix[3][3] = 1; + + if (determinant4x4(perspectiveMatrix) == 0) + return false; + + // First, isolate perspective. This is the messiest. + if (localMatrix[0][3] != 0 || localMatrix[1][3] != 0 || localMatrix[2][3] != 0) { + // rightHandSide is the right hand side of the equation. + Vector4 rightHandSide; + rightHandSide[0] = localMatrix[0][3]; + rightHandSide[1] = localMatrix[1][3]; + rightHandSide[2] = localMatrix[2][3]; + rightHandSide[3] = localMatrix[3][3]; + + // Solve the equation by inverting perspectiveMatrix and multiplying + // rightHandSide by the inverse. (This is the easiest way, not + // necessarily the best.) + TransformationMatrix::Matrix4 inversePerspectiveMatrix, transposedInversePerspectiveMatrix; + inverse(perspectiveMatrix, inversePerspectiveMatrix); + transposeMatrix4(inversePerspectiveMatrix, transposedInversePerspectiveMatrix); + + Vector4 perspectivePoint; + v4MulPointByMatrix(rightHandSide, transposedInversePerspectiveMatrix, perspectivePoint); + + result.perspectiveX = perspectivePoint[0]; + result.perspectiveY = perspectivePoint[1]; + result.perspectiveZ = perspectivePoint[2]; + result.perspectiveW = perspectivePoint[3]; + + // Clear the perspective partition + localMatrix[0][3] = localMatrix[1][3] = localMatrix[2][3] = 0; + localMatrix[3][3] = 1; + } else { + // No perspective. + result.perspectiveX = result.perspectiveY = result.perspectiveZ = 0; + result.perspectiveW = 1; + } + + // Next take care of translation (easy). + result.translateX = localMatrix[3][0]; + localMatrix[3][0] = 0; + result.translateY = localMatrix[3][1]; + localMatrix[3][1] = 0; + result.translateZ = localMatrix[3][2]; + localMatrix[3][2] = 0; + + // Vector4 type and functions need to be added to the common set. + Vector3 row[3], pdum3; + + // Now get scale and shear. + for (i = 0; i < 3; i++) { + row[i][0] = localMatrix[i][0]; + row[i][1] = localMatrix[i][1]; + row[i][2] = localMatrix[i][2]; + } + + // Compute X scale factor and normalize first row. + result.scaleX = v3Length(row[0]); + v3Scale(row[0], 1.0); + + // Compute XY shear factor and make 2nd row orthogonal to 1st. + result.skewXY = v3Dot(row[0], row[1]); + v3Combine(row[1], row[0], row[1], 1.0, -result.skewXY); + + // Now, compute Y scale and normalize 2nd row. + result.scaleY = v3Length(row[1]); + v3Scale(row[1], 1.0); + result.skewXY /= result.scaleY; + + // Compute XZ and YZ shears, orthogonalize 3rd row. + result.skewXZ = v3Dot(row[0], row[2]); + v3Combine(row[2], row[0], row[2], 1.0, -result.skewXZ); + result.skewYZ = v3Dot(row[1], row[2]); + v3Combine(row[2], row[1], row[2], 1.0, -result.skewYZ); + + // Next, get Z scale and normalize 3rd row. + result.scaleZ = v3Length(row[2]); + v3Scale(row[2], 1.0); + result.skewXZ /= result.scaleZ; + result.skewYZ /= result.scaleZ; + + // At this point, the matrix (in rows[]) is orthonormal. + // Check for a coordinate system flip. If the determinant + // is -1, then negate the matrix and the scaling factors. + v3Cross(row[1], row[2], pdum3); + if (v3Dot(row[0], pdum3) < 0) { + + result.scaleX *= -1; + result.scaleY *= -1; + result.scaleZ *= -1; + + for (i = 0; i < 3; i++) { + row[i][0] *= -1; + row[i][1] *= -1; + row[i][2] *= -1; + } + } + + // Now, get the rotations out, as described in the gem. + + result.rotateY = asin(-row[0][2]); + if (cos(result.rotateY) != 0) { + result.rotateX = atan2(row[1][2], row[2][2]); + result.rotateZ = atan2(row[0][1], row[0][0]); + } else { + result.rotateX = atan2(-row[2][0], row[1][1]); + result.rotateZ = 0; + } + + double s, t, x, y, z, w; + + t = row[0][0] + row[1][1] + row[2][2] + 1.0; + + if (t > 1e-4) { + s = 0.5 / sqrt(t); + w = 0.25 / s; + x = (row[2][1] - row[1][2]) * s; + y = (row[0][2] - row[2][0]) * s; + z = (row[1][0] - row[0][1]) * s; + } else if (row[0][0] > row[1][1] && row[0][0] > row[2][2]) { + s = sqrt (1.0 + row[0][0] - row[1][1] - row[2][2]) * 2.0; // S=4*qx + x = 0.25 * s; + y = (row[0][1] + row[1][0]) / s; + z = (row[0][2] + row[2][0]) / s; + w = (row[2][1] - row[1][2]) / s; + } else if (row[1][1] > row[2][2]) { + s = sqrt (1.0 + row[1][1] - row[0][0] - row[2][2]) * 2.0; // S=4*qy + x = (row[0][1] + row[1][0]) / s; + y = 0.25 * s; + z = (row[1][2] + row[2][1]) / s; + w = (row[0][2] - row[2][0]) / s; + } else { + s = sqrt(1.0 + row[2][2] - row[0][0] - row[1][1]) * 2.0; // S=4*qz + x = (row[0][2] + row[2][0]) / s; + y = (row[1][2] + row[2][1]) / s; + z = 0.25 * s; + w = (row[1][0] - row[0][1]) / s; + } + + result.quaternionX = x; + result.quaternionY = y; + result.quaternionZ = z; + result.quaternionW = w; + + return true; + } + + // Perform a spherical linear interpolation between the two + // passed quaternions with 0 <= t <= 1 + static void slerp(double qa[4], const double qb[4], double t) + { + double ax, ay, az, aw; + double bx, by, bz, bw; + double cx, cy, cz, cw; + double angle; + double th, invth, scale, invscale; + + ax = qa[0]; ay = qa[1]; az = qa[2]; aw = qa[3]; + bx = qb[0]; by = qb[1]; bz = qb[2]; bw = qb[3]; + + angle = ax * bx + ay * by + az * bz + aw * bw; + + if (angle < 0.0) { + ax = -ax; ay = -ay; + az = -az; aw = -aw; + angle = -angle; + } + + if (angle + 1.0 > .05) { + if (1.0 - angle >= .05) { + th = acos (angle); + invth = 1.0 / sin (th); + scale = sin (th * (1.0 - t)) * invth; + invscale = sin (th * t) * invth; + } else { + scale = 1.0 - t; + invscale = t; + } + } else { + bx = -ay; + by = ax; + bz = -aw; + bw = az; + scale = sin(M_PI * (.5 - t)); + invscale = sin (M_PI * t); + } + + cx = ax * scale + bx * invscale; + cy = ay * scale + by * invscale; + cz = az * scale + bz * invscale; + cw = aw * scale + bw * invscale; + + qa[0] = cx; qa[1] = cy; qa[2] = cz; qa[3] = cw; + } + + // End of Supporting Math Functions + + TransformationMatrix::TransformationMatrix(const CGAffineTransform& t) + { + setMatrix(t.a, t.b, t.c, t.d, t.tx, t.ty); + } + + TransformationMatrix::TransformationMatrix(const CATransform3D& t) + { + setMatrix( + t.m11, t.m12, t.m13, t.m14, + t.m21, t.m22, t.m23, t.m24, + t.m31, t.m32, t.m33, t.m34, + t.m41, t.m42, t.m43, t.m44); + } + + CATransform3D TransformationMatrix::transform3d() const + { + CATransform3D t; + t.m11 = narrowPrecisionToFloat(m11()); + t.m12 = narrowPrecisionToFloat(m12()); + t.m13 = narrowPrecisionToFloat(m13()); + t.m14 = narrowPrecisionToFloat(m14()); + t.m21 = narrowPrecisionToFloat(m21()); + t.m22 = narrowPrecisionToFloat(m22()); + t.m23 = narrowPrecisionToFloat(m23()); + t.m24 = narrowPrecisionToFloat(m24()); + t.m31 = narrowPrecisionToFloat(m31()); + t.m32 = narrowPrecisionToFloat(m32()); + t.m33 = narrowPrecisionToFloat(m33()); + t.m34 = narrowPrecisionToFloat(m34()); + t.m41 = narrowPrecisionToFloat(m41()); + t.m42 = narrowPrecisionToFloat(m42()); + t.m43 = narrowPrecisionToFloat(m43()); + t.m44 = narrowPrecisionToFloat(m44()); + return t; + } + + CGAffineTransform TransformationMatrix::affineTransform () const + { + CGAffineTransform t; + t.a = narrowPrecisionToFloat(m11()); + t.b = narrowPrecisionToFloat(m12()); + t.c = narrowPrecisionToFloat(m21()); + t.d = narrowPrecisionToFloat(m22()); + t.tx = narrowPrecisionToFloat(m41()); + t.ty = narrowPrecisionToFloat(m42()); + return t; + } + + TransformationMatrix::operator CATransform3D() const + { + return transform3d(); + } + + TransformationMatrix& TransformationMatrix::scale(double s) + { + return scaleNonUniform(s, s); + } + + TransformationMatrix& TransformationMatrix::rotateFromVector(double x, double y) + { + return rotate(rad2deg(atan2(y, x))); + } + + TransformationMatrix& TransformationMatrix::flipX() + { + return scaleNonUniform(-1.0, 1.0); + } + + TransformationMatrix& TransformationMatrix::flipY() + { + return scaleNonUniform(1.0, -1.0); + } + + TransformationMatrix& TransformationMatrix::scaleNonUniform(double sx, double sy) + { + m_matrix[0][0] *= sx; + m_matrix[0][1] *= sx; + m_matrix[0][2] *= sx; + m_matrix[0][3] *= sx; + + m_matrix[1][0] *= sy; + m_matrix[1][1] *= sy; + m_matrix[1][2] *= sy; + m_matrix[1][3] *= sy; + return *this; + } + + TransformationMatrix& TransformationMatrix::scale3d(double sx, double sy, double sz) + { + scaleNonUniform(sx, sy); + + m_matrix[2][0] *= sz; + m_matrix[2][1] *= sz; + m_matrix[2][2] *= sz; + m_matrix[2][3] *= sz; + return *this; + } + + TransformationMatrix& TransformationMatrix::rotate3d(double x, double y, double z, double angle) + { + // Normalize the axis of rotation + double length = sqrt(x * x + y * y + z * z); + if (length == 0) { + // A direction vector that cannot be normalized, such as [0, 0, 0], will cause the rotation to not be applied. + return *this; + } else if (length != 1) { + x /= length; + y /= length; + z /= length; + } + + // Angles are in degrees. Switch to radians. + angle = deg2rad(angle); + + double sinTheta = sin(angle); + double cosTheta = cos(angle); + + TransformationMatrix mat; + + // Optimize cases where the axis is along a major axis + if (x == 1.0 && y == 0.0 && z == 0.0) { + mat.m_matrix[0][0] = 1.0; + mat.m_matrix[0][1] = 0.0; + mat.m_matrix[0][2] = 0.0; + mat.m_matrix[1][0] = 0.0; + mat.m_matrix[1][1] = cosTheta; + mat.m_matrix[1][2] = sinTheta; + mat.m_matrix[2][0] = 0.0; + mat.m_matrix[2][1] = -sinTheta; + mat.m_matrix[2][2] = cosTheta; + mat.m_matrix[0][3] = mat.m_matrix[1][3] = mat.m_matrix[2][3] = 0.0; + mat.m_matrix[3][0] = mat.m_matrix[3][1] = mat.m_matrix[3][2] = 0.0; + mat.m_matrix[3][3] = 1.0; + } else if (x == 0.0 && y == 1.0 && z == 0.0) { + mat.m_matrix[0][0] = cosTheta; + mat.m_matrix[0][1] = 0.0; + mat.m_matrix[0][2] = -sinTheta; + mat.m_matrix[1][0] = 0.0; + mat.m_matrix[1][1] = 1.0; + mat.m_matrix[1][2] = 0.0; + mat.m_matrix[2][0] = sinTheta; + mat.m_matrix[2][1] = 0.0; + mat.m_matrix[2][2] = cosTheta; + mat.m_matrix[0][3] = mat.m_matrix[1][3] = mat.m_matrix[2][3] = 0.0; + mat.m_matrix[3][0] = mat.m_matrix[3][1] = mat.m_matrix[3][2] = 0.0; + mat.m_matrix[3][3] = 1.0; + } else if (x == 0.0 && y == 0.0 && z == 1.0) { + mat.m_matrix[0][0] = cosTheta; + mat.m_matrix[0][1] = sinTheta; + mat.m_matrix[0][2] = 0.0; + mat.m_matrix[1][0] = -sinTheta; + mat.m_matrix[1][1] = cosTheta; + mat.m_matrix[1][2] = 0.0; + mat.m_matrix[2][0] = 0.0; + mat.m_matrix[2][1] = 0.0; + mat.m_matrix[2][2] = 1.0; + mat.m_matrix[0][3] = mat.m_matrix[1][3] = mat.m_matrix[2][3] = 0.0; + mat.m_matrix[3][0] = mat.m_matrix[3][1] = mat.m_matrix[3][2] = 0.0; + mat.m_matrix[3][3] = 1.0; + } else { + // This case is the rotation about an arbitrary unit vector. + // + // Formula is adapted from Wikipedia article on Rotation matrix, + // http://en.wikipedia.org/wiki/Rotation_matrix#Rotation_matrix_from_axis_and_angle + // + // An alternate resource with the same matrix: http://www.fastgraph.com/makegames/3drotation/ + // + double oneMinusCosTheta = 1 - cosTheta; + mat.m_matrix[0][0] = cosTheta + x * x * oneMinusCosTheta; + mat.m_matrix[0][1] = y * x * oneMinusCosTheta + z * sinTheta; + mat.m_matrix[0][2] = z * x * oneMinusCosTheta - y * sinTheta; + mat.m_matrix[1][0] = x * y * oneMinusCosTheta - z * sinTheta; + mat.m_matrix[1][1] = cosTheta + y * y * oneMinusCosTheta; + mat.m_matrix[1][2] = z * y * oneMinusCosTheta + x * sinTheta; + mat.m_matrix[2][0] = x * z * oneMinusCosTheta + y * sinTheta; + mat.m_matrix[2][1] = y * z * oneMinusCosTheta - x * sinTheta; + mat.m_matrix[2][2] = cosTheta + z * z * oneMinusCosTheta; + mat.m_matrix[0][3] = mat.m_matrix[1][3] = mat.m_matrix[2][3] = 0.0; + mat.m_matrix[3][0] = mat.m_matrix[3][1] = mat.m_matrix[3][2] = 0.0; + mat.m_matrix[3][3] = 1.0; + } + multiply(mat); + return *this; + } + + TransformationMatrix& TransformationMatrix::rotate3d(double rx, double ry, double rz) + { + // Angles are in degrees. Switch to radians. + rx = deg2rad(rx); + ry = deg2rad(ry); + rz = deg2rad(rz); + + TransformationMatrix mat; + + double sinTheta = sin(rz); + double cosTheta = cos(rz); + + mat.m_matrix[0][0] = cosTheta; + mat.m_matrix[0][1] = sinTheta; + mat.m_matrix[0][2] = 0.0; + mat.m_matrix[1][0] = -sinTheta; + mat.m_matrix[1][1] = cosTheta; + mat.m_matrix[1][2] = 0.0; + mat.m_matrix[2][0] = 0.0; + mat.m_matrix[2][1] = 0.0; + mat.m_matrix[2][2] = 1.0; + mat.m_matrix[0][3] = mat.m_matrix[1][3] = mat.m_matrix[2][3] = 0.0; + mat.m_matrix[3][0] = mat.m_matrix[3][1] = mat.m_matrix[3][2] = 0.0; + mat.m_matrix[3][3] = 1.0; + + TransformationMatrix rmat(mat); + + sinTheta = sin(ry); + cosTheta = cos(ry); + + mat.m_matrix[0][0] = cosTheta; + mat.m_matrix[0][1] = 0.0; + mat.m_matrix[0][2] = -sinTheta; + mat.m_matrix[1][0] = 0.0; + mat.m_matrix[1][1] = 1.0; + mat.m_matrix[1][2] = 0.0; + mat.m_matrix[2][0] = sinTheta; + mat.m_matrix[2][1] = 0.0; + mat.m_matrix[2][2] = cosTheta; + mat.m_matrix[0][3] = mat.m_matrix[1][3] = mat.m_matrix[2][3] = 0.0; + mat.m_matrix[3][0] = mat.m_matrix[3][1] = mat.m_matrix[3][2] = 0.0; + mat.m_matrix[3][3] = 1.0; + + rmat.multiply(mat); + + sinTheta = sin(rx); + cosTheta = cos(rx); + + mat.m_matrix[0][0] = 1.0; + mat.m_matrix[0][1] = 0.0; + mat.m_matrix[0][2] = 0.0; + mat.m_matrix[1][0] = 0.0; + mat.m_matrix[1][1] = cosTheta; + mat.m_matrix[1][2] = sinTheta; + mat.m_matrix[2][0] = 0.0; + mat.m_matrix[2][1] = -sinTheta; + mat.m_matrix[2][2] = cosTheta; + mat.m_matrix[0][3] = mat.m_matrix[1][3] = mat.m_matrix[2][3] = 0.0; + mat.m_matrix[3][0] = mat.m_matrix[3][1] = mat.m_matrix[3][2] = 0.0; + mat.m_matrix[3][3] = 1.0; + + rmat.multiply(mat); + + multiply(rmat); + return *this; + } + + TransformationMatrix& TransformationMatrix::translate(double tx, double ty) + { + m_matrix[3][0] += tx * m_matrix[0][0] + ty * m_matrix[1][0]; + m_matrix[3][1] += tx * m_matrix[0][1] + ty * m_matrix[1][1]; + m_matrix[3][2] += tx * m_matrix[0][2] + ty * m_matrix[1][2]; + m_matrix[3][3] += tx * m_matrix[0][3] + ty * m_matrix[1][3]; + return *this; + } + + TransformationMatrix& TransformationMatrix::translate3d(double tx, double ty, double tz) + { + m_matrix[3][0] += tx * m_matrix[0][0] + ty * m_matrix[1][0] + tz * m_matrix[2][0]; + m_matrix[3][1] += tx * m_matrix[0][1] + ty * m_matrix[1][1] + tz * m_matrix[2][1]; + m_matrix[3][2] += tx * m_matrix[0][2] + ty * m_matrix[1][2] + tz * m_matrix[2][2]; + m_matrix[3][3] += tx * m_matrix[0][3] + ty * m_matrix[1][3] + tz * m_matrix[2][3]; + return *this; + } + + TransformationMatrix& TransformationMatrix::translateRight(double tx, double ty) + { + if (tx != 0) { + m_matrix[0][0] += m_matrix[0][3] * tx; + m_matrix[1][0] += m_matrix[1][3] * tx; + m_matrix[2][0] += m_matrix[2][3] * tx; + m_matrix[3][0] += m_matrix[3][3] * tx; + } + + if (ty != 0) { + m_matrix[0][1] += m_matrix[0][3] * ty; + m_matrix[1][1] += m_matrix[1][3] * ty; + m_matrix[2][1] += m_matrix[2][3] * ty; + m_matrix[3][1] += m_matrix[3][3] * ty; + } + + return *this; + } + + TransformationMatrix& TransformationMatrix::translateRight3d(double tx, double ty, double tz) + { + translateRight(tx, ty); + if (tz != 0) { + m_matrix[0][2] += m_matrix[0][3] * tz; + m_matrix[1][2] += m_matrix[1][3] * tz; + m_matrix[2][2] += m_matrix[2][3] * tz; + m_matrix[3][2] += m_matrix[3][3] * tz; + } + + return *this; + } + + TransformationMatrix& TransformationMatrix::skew(double sx, double sy) + { + // angles are in degrees. Switch to radians + sx = deg2rad(sx); + sy = deg2rad(sy); + + TransformationMatrix mat; + mat.m_matrix[0][1] = tan(sy); // note that the y shear goes in the first row + mat.m_matrix[1][0] = tan(sx); // and the x shear in the second row + + multiply(mat); + return *this; + } + + TransformationMatrix& TransformationMatrix::applyPerspective(double p) + { + TransformationMatrix mat; + if (p != 0) + mat.m_matrix[2][3] = -1/p; + + multiply(mat); + return *this; + } + + // this = mat * this. + TransformationMatrix& TransformationMatrix::multiply(const TransformationMatrix& mat) + { + Matrix4 tmp; + + tmp[0][0] = (mat.m_matrix[0][0] * m_matrix[0][0] + mat.m_matrix[0][1] * m_matrix[1][0] + + mat.m_matrix[0][2] * m_matrix[2][0] + mat.m_matrix[0][3] * m_matrix[3][0]); + tmp[0][1] = (mat.m_matrix[0][0] * m_matrix[0][1] + mat.m_matrix[0][1] * m_matrix[1][1] + + mat.m_matrix[0][2] * m_matrix[2][1] + mat.m_matrix[0][3] * m_matrix[3][1]); + tmp[0][2] = (mat.m_matrix[0][0] * m_matrix[0][2] + mat.m_matrix[0][1] * m_matrix[1][2] + + mat.m_matrix[0][2] * m_matrix[2][2] + mat.m_matrix[0][3] * m_matrix[3][2]); + tmp[0][3] = (mat.m_matrix[0][0] * m_matrix[0][3] + mat.m_matrix[0][1] * m_matrix[1][3] + + mat.m_matrix[0][2] * m_matrix[2][3] + mat.m_matrix[0][3] * m_matrix[3][3]); + + tmp[1][0] = (mat.m_matrix[1][0] * m_matrix[0][0] + mat.m_matrix[1][1] * m_matrix[1][0] + + mat.m_matrix[1][2] * m_matrix[2][0] + mat.m_matrix[1][3] * m_matrix[3][0]); + tmp[1][1] = (mat.m_matrix[1][0] * m_matrix[0][1] + mat.m_matrix[1][1] * m_matrix[1][1] + + mat.m_matrix[1][2] * m_matrix[2][1] + mat.m_matrix[1][3] * m_matrix[3][1]); + tmp[1][2] = (mat.m_matrix[1][0] * m_matrix[0][2] + mat.m_matrix[1][1] * m_matrix[1][2] + + mat.m_matrix[1][2] * m_matrix[2][2] + mat.m_matrix[1][3] * m_matrix[3][2]); + tmp[1][3] = (mat.m_matrix[1][0] * m_matrix[0][3] + mat.m_matrix[1][1] * m_matrix[1][3] + + mat.m_matrix[1][2] * m_matrix[2][3] + mat.m_matrix[1][3] * m_matrix[3][3]); + + tmp[2][0] = (mat.m_matrix[2][0] * m_matrix[0][0] + mat.m_matrix[2][1] * m_matrix[1][0] + + mat.m_matrix[2][2] * m_matrix[2][0] + mat.m_matrix[2][3] * m_matrix[3][0]); + tmp[2][1] = (mat.m_matrix[2][0] * m_matrix[0][1] + mat.m_matrix[2][1] * m_matrix[1][1] + + mat.m_matrix[2][2] * m_matrix[2][1] + mat.m_matrix[2][3] * m_matrix[3][1]); + tmp[2][2] = (mat.m_matrix[2][0] * m_matrix[0][2] + mat.m_matrix[2][1] * m_matrix[1][2] + + mat.m_matrix[2][2] * m_matrix[2][2] + mat.m_matrix[2][3] * m_matrix[3][2]); + tmp[2][3] = (mat.m_matrix[2][0] * m_matrix[0][3] + mat.m_matrix[2][1] * m_matrix[1][3] + + mat.m_matrix[2][2] * m_matrix[2][3] + mat.m_matrix[2][3] * m_matrix[3][3]); + + tmp[3][0] = (mat.m_matrix[3][0] * m_matrix[0][0] + mat.m_matrix[3][1] * m_matrix[1][0] + + mat.m_matrix[3][2] * m_matrix[2][0] + mat.m_matrix[3][3] * m_matrix[3][0]); + tmp[3][1] = (mat.m_matrix[3][0] * m_matrix[0][1] + mat.m_matrix[3][1] * m_matrix[1][1] + + mat.m_matrix[3][2] * m_matrix[2][1] + mat.m_matrix[3][3] * m_matrix[3][1]); + tmp[3][2] = (mat.m_matrix[3][0] * m_matrix[0][2] + mat.m_matrix[3][1] * m_matrix[1][2] + + mat.m_matrix[3][2] * m_matrix[2][2] + mat.m_matrix[3][3] * m_matrix[3][2]); + tmp[3][3] = (mat.m_matrix[3][0] * m_matrix[0][3] + mat.m_matrix[3][1] * m_matrix[1][3] + + mat.m_matrix[3][2] * m_matrix[2][3] + mat.m_matrix[3][3] * m_matrix[3][3]); + + setMatrix(tmp); + return *this; + } + + void TransformationMatrix::multVecMatrix(double x, double y, double& resultX, double& resultY) const + { + resultX = m_matrix[3][0] + x * m_matrix[0][0] + y * m_matrix[1][0]; + resultY = m_matrix[3][1] + x * m_matrix[0][1] + y * m_matrix[1][1]; + double w = m_matrix[3][3] + x * m_matrix[0][3] + y * m_matrix[1][3]; + if (w != 1 && w != 0) { + resultX /= w; + resultY /= w; + } + } + + void TransformationMatrix::multVecMatrix(double x, double y, double z, double& resultX, double& resultY, double& resultZ) const + { + resultX = m_matrix[3][0] + x * m_matrix[0][0] + y * m_matrix[1][0] + z * m_matrix[2][0]; + resultY = m_matrix[3][1] + x * m_matrix[0][1] + y * m_matrix[1][1] + z * m_matrix[2][1]; + resultZ = m_matrix[3][2] + x * m_matrix[0][2] + y * m_matrix[1][2] + z * m_matrix[2][2]; + double w = m_matrix[3][3] + x * m_matrix[0][3] + y * m_matrix[1][3] + z * m_matrix[2][3]; + if (w != 1 && w != 0) { + resultX /= w; + resultY /= w; + resultZ /= w; + } + } + + bool TransformationMatrix::isInvertible() const + { + if (isIdentityOrTranslation()) + return true; + + double det = WebCore::determinant4x4(m_matrix); + + if (fabs(det) < SMALL_NUMBER) + return false; + + return true; + } + + TransformationMatrix TransformationMatrix::inverse() const + { + if (isIdentityOrTranslation()) { + // identity matrix + if (m_matrix[3][0] == 0 && m_matrix[3][1] == 0 && m_matrix[3][2] == 0) + return TransformationMatrix(); + + // translation + return TransformationMatrix(1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + -m_matrix[3][0], -m_matrix[3][1], -m_matrix[3][2], 1); + } + + TransformationMatrix invMat; + bool inverted = WebCore::inverse(m_matrix, invMat.m_matrix); + if (!inverted) + return TransformationMatrix(); + + return invMat; + } + + void TransformationMatrix::makeAffine() + { + m_matrix[0][2] = 0; + m_matrix[0][3] = 0; + + m_matrix[1][2] = 0; + m_matrix[1][3] = 0; + + m_matrix[2][0] = 0; + m_matrix[2][1] = 0; + m_matrix[2][2] = 1; + m_matrix[2][3] = 0; + + m_matrix[3][2] = 0; + m_matrix[3][3] = 1; + } + + static inline void blendFloat(double& from, double to, double progress) + { + if (from != to) + from = from + (to - from) * progress; + } + + void TransformationMatrix::blend(const TransformationMatrix& from, double progress) + { + if (from.isIdentity() && isIdentity()) + return; + + // decompose + DecomposedType fromDecomp; + DecomposedType toDecomp; + from.decompose(fromDecomp); + decompose(toDecomp); + + // interpolate + blendFloat(fromDecomp.scaleX, toDecomp.scaleX, progress); + blendFloat(fromDecomp.scaleY, toDecomp.scaleY, progress); + blendFloat(fromDecomp.scaleZ, toDecomp.scaleZ, progress); + blendFloat(fromDecomp.skewXY, toDecomp.skewXY, progress); + blendFloat(fromDecomp.skewXZ, toDecomp.skewXZ, progress); + blendFloat(fromDecomp.skewYZ, toDecomp.skewYZ, progress); + blendFloat(fromDecomp.translateX, toDecomp.translateX, progress); + blendFloat(fromDecomp.translateY, toDecomp.translateY, progress); + blendFloat(fromDecomp.translateZ, toDecomp.translateZ, progress); + blendFloat(fromDecomp.perspectiveX, toDecomp.perspectiveX, progress); + blendFloat(fromDecomp.perspectiveY, toDecomp.perspectiveY, progress); + blendFloat(fromDecomp.perspectiveZ, toDecomp.perspectiveZ, progress); + blendFloat(fromDecomp.perspectiveW, toDecomp.perspectiveW, progress); + + slerp(&fromDecomp.quaternionX, &toDecomp.quaternionX, progress); + + // recompose + recompose(fromDecomp); + } + + bool TransformationMatrix::decompose(DecomposedType& decomp) const + { + if (isIdentity()) { + memset(&decomp, 0, sizeof(decomp)); + decomp.perspectiveW = 1; + decomp.scaleX = 1; + decomp.scaleY = 1; + decomp.scaleZ = 1; + } + + if (!WebCore::decompose(m_matrix, decomp)) + return false; + return true; + } + + void TransformationMatrix::recompose(const DecomposedType& decomp, bool useEulerAngle) + { + makeIdentity(); + + // first apply perspective + m_matrix[0][3] = decomp.perspectiveX; + m_matrix[1][3] = decomp.perspectiveY; + m_matrix[2][3] = decomp.perspectiveZ; + m_matrix[3][3] = decomp.perspectiveW; + + // now translate + translate3d(decomp.translateX, decomp.translateY, decomp.translateZ); + + if (!useEulerAngle) { + // apply rotation + double xx = decomp.quaternionX * decomp.quaternionX; + double xy = decomp.quaternionX * decomp.quaternionY; + double xz = decomp.quaternionX * decomp.quaternionZ; + double xw = decomp.quaternionX * decomp.quaternionW; + double yy = decomp.quaternionY * decomp.quaternionY; + double yz = decomp.quaternionY * decomp.quaternionZ; + double yw = decomp.quaternionY * decomp.quaternionW; + double zz = decomp.quaternionZ * decomp.quaternionZ; + double zw = decomp.quaternionZ * decomp.quaternionW; + + // Construct a composite rotation matrix from the quaternion values + TransformationMatrix rotationMatrix(1 - 2 * (yy + zz), 2 * (xy - zw), 2 * (xz + yw), 0, + 2 * (xy + zw), 1 - 2 * (xx + zz), 2 * (yz - xw), 0, + 2 * (xz - yw), 2 * (yz + xw), 1 - 2 * (xx + yy), 0, + 0, 0, 0, 1); + + multiply(rotationMatrix); + } else { + rotate3d(1.0, 0.0, 0.0, rad2deg(decomp.rotateX)); + rotate3d(0.0, 1.0, 0.0, rad2deg(decomp.rotateY)); + rotate3d(0.0, 0.0, 1.0, rad2deg(decomp.rotateZ)); + } + + // now apply skew + if (decomp.skewYZ) { + TransformationMatrix tmp; + tmp.setM32(decomp.skewYZ); + multiply(tmp); + } + + if (decomp.skewXZ) { + TransformationMatrix tmp; + tmp.setM31(decomp.skewXZ); + multiply(tmp); + } + + if (decomp.skewXY) { + TransformationMatrix tmp; + tmp.setM21(decomp.skewXY); + multiply(tmp); + } + + // finally, apply scale + scale3d(decomp.scaleX, decomp.scaleY, decomp.scaleZ); + } +} \ No newline at end of file diff --git a/Example/Pods/pop/pop/WebCore/TransformationMatrix.h b/Example/Pods/pop/pop/WebCore/TransformationMatrix.h new file mode 100644 index 0000000..9dad2e9 --- /dev/null +++ b/Example/Pods/pop/pop/WebCore/TransformationMatrix.h @@ -0,0 +1,277 @@ +/* + * Copyright (C) 2005, 2006 Apple Computer, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef TransformationMatrix_h +#define TransformationMatrix_h + +#include //for memcpy +#include +#include + +namespace WebCore { + + class TransformationMatrix { + public: + + typedef double Matrix4[4][4]; + + TransformationMatrix() { makeIdentity(); } + TransformationMatrix(const TransformationMatrix& t) { *this = t; } + TransformationMatrix(double a, double b, double c, double d, double e, double f) { setMatrix(a, b, c, d, e, f); } + TransformationMatrix(double m11, double m12, double m13, double m14, + double m21, double m22, double m23, double m24, + double m31, double m32, double m33, double m34, + double m41, double m42, double m43, double m44) + { + setMatrix(m11, m12, m13, m14, m21, m22, m23, m24, m31, m32, m33, m34, m41, m42, m43, m44); + } + + void setMatrix(double a, double b, double c, double d, double e, double f) + { + m_matrix[0][0] = a; m_matrix[0][1] = b; m_matrix[0][2] = 0; m_matrix[0][3] = 0; + m_matrix[1][0] = c; m_matrix[1][1] = d; m_matrix[1][2] = 0; m_matrix[1][3] = 0; + m_matrix[2][0] = 0; m_matrix[2][1] = 0; m_matrix[2][2] = 1; m_matrix[2][3] = 0; + m_matrix[3][0] = e; m_matrix[3][1] = f; m_matrix[3][2] = 0; m_matrix[3][3] = 1; + } + + void setMatrix(double m11, double m12, double m13, double m14, + double m21, double m22, double m23, double m24, + double m31, double m32, double m33, double m34, + double m41, double m42, double m43, double m44) + { + m_matrix[0][0] = m11; m_matrix[0][1] = m12; m_matrix[0][2] = m13; m_matrix[0][3] = m14; + m_matrix[1][0] = m21; m_matrix[1][1] = m22; m_matrix[1][2] = m23; m_matrix[1][3] = m24; + m_matrix[2][0] = m31; m_matrix[2][1] = m32; m_matrix[2][2] = m33; m_matrix[2][3] = m34; + m_matrix[3][0] = m41; m_matrix[3][1] = m42; m_matrix[3][2] = m43; m_matrix[3][3] = m44; + } + + TransformationMatrix& operator =(const TransformationMatrix &t) + { + setMatrix(t.m_matrix); + return *this; + } + + TransformationMatrix& makeIdentity() + { + setMatrix(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + return *this; + } + + bool isIdentity() const + { + return m_matrix[0][0] == 1 && m_matrix[0][1] == 0 && m_matrix[0][2] == 0 && m_matrix[0][3] == 0 && + m_matrix[1][0] == 0 && m_matrix[1][1] == 1 && m_matrix[1][2] == 0 && m_matrix[1][3] == 0 && + m_matrix[2][0] == 0 && m_matrix[2][1] == 0 && m_matrix[2][2] == 1 && m_matrix[2][3] == 0 && + m_matrix[3][0] == 0 && m_matrix[3][1] == 0 && m_matrix[3][2] == 0 && m_matrix[3][3] == 1; + } + + // This form preserves the double math from input to output + void map(double x, double y, double& x2, double& y2) const { multVecMatrix(x, y, x2, y2); } + + double m11() const { return m_matrix[0][0]; } + void setM11(double f) { m_matrix[0][0] = f; } + double m12() const { return m_matrix[0][1]; } + void setM12(double f) { m_matrix[0][1] = f; } + double m13() const { return m_matrix[0][2]; } + void setM13(double f) { m_matrix[0][2] = f; } + double m14() const { return m_matrix[0][3]; } + void setM14(double f) { m_matrix[0][3] = f; } + double m21() const { return m_matrix[1][0]; } + void setM21(double f) { m_matrix[1][0] = f; } + double m22() const { return m_matrix[1][1]; } + void setM22(double f) { m_matrix[1][1] = f; } + double m23() const { return m_matrix[1][2]; } + void setM23(double f) { m_matrix[1][2] = f; } + double m24() const { return m_matrix[1][3]; } + void setM24(double f) { m_matrix[1][3] = f; } + double m31() const { return m_matrix[2][0]; } + void setM31(double f) { m_matrix[2][0] = f; } + double m32() const { return m_matrix[2][1]; } + void setM32(double f) { m_matrix[2][1] = f; } + double m33() const { return m_matrix[2][2]; } + void setM33(double f) { m_matrix[2][2] = f; } + double m34() const { return m_matrix[2][3]; } + void setM34(double f) { m_matrix[2][3] = f; } + double m41() const { return m_matrix[3][0]; } + void setM41(double f) { m_matrix[3][0] = f; } + double m42() const { return m_matrix[3][1]; } + void setM42(double f) { m_matrix[3][1] = f; } + double m43() const { return m_matrix[3][2]; } + void setM43(double f) { m_matrix[3][2] = f; } + double m44() const { return m_matrix[3][3]; } + void setM44(double f) { m_matrix[3][3] = f; } + + double a() const { return m_matrix[0][0]; } + void setA(double a) { m_matrix[0][0] = a; } + + double b() const { return m_matrix[0][1]; } + void setB(double b) { m_matrix[0][1] = b; } + + double c() const { return m_matrix[1][0]; } + void setC(double c) { m_matrix[1][0] = c; } + + double d() const { return m_matrix[1][1]; } + void setD(double d) { m_matrix[1][1] = d; } + + double e() const { return m_matrix[3][0]; } + void setE(double e) { m_matrix[3][0] = e; } + + double f() const { return m_matrix[3][1]; } + void setF(double f) { m_matrix[3][1] = f; } + + // this = this * mat + TransformationMatrix& multiply(const TransformationMatrix&); + + TransformationMatrix& scale(double); + TransformationMatrix& scaleNonUniform(double sx, double sy); + TransformationMatrix& scale3d(double sx, double sy, double sz); + + TransformationMatrix& rotate(double d) { return rotate3d(0, 0, d); } + TransformationMatrix& rotateFromVector(double x, double y); + TransformationMatrix& rotate3d(double rx, double ry, double rz); + + // The vector (x,y,z) is normalized if it's not already. A vector of + // (0,0,0) uses a vector of (0,0,1). + TransformationMatrix& rotate3d(double x, double y, double z, double angle); + + TransformationMatrix& translate(double tx, double ty); + TransformationMatrix& translate3d(double tx, double ty, double tz); + + // translation added with a post-multiply + TransformationMatrix& translateRight(double tx, double ty); + TransformationMatrix& translateRight3d(double tx, double ty, double tz); + + TransformationMatrix& flipX(); + TransformationMatrix& flipY(); + TransformationMatrix& skew(double angleX, double angleY); + TransformationMatrix& skewX(double angle) { return skew(angle, 0); } + TransformationMatrix& skewY(double angle) { return skew(0, angle); } + + TransformationMatrix& applyPerspective(double p); + bool hasPerspective() const { return m_matrix[2][3] != 0.0f; } + + bool isInvertible() const; + + // This method returns the identity matrix if it is not invertible. + // Use isInvertible() before calling this if you need to know. + TransformationMatrix inverse() const; + + // decompose the matrix into its component parts + typedef struct { + double scaleX, scaleY, scaleZ; + double skewXY, skewXZ, skewYZ; + double rotateX, rotateY, rotateZ; + double quaternionX, quaternionY, quaternionZ, quaternionW; + double translateX, translateY, translateZ; + double perspectiveX, perspectiveY, perspectiveZ, perspectiveW; + } DecomposedType; + + bool decompose(DecomposedType& decomp) const; + void recompose(const DecomposedType& decomp, bool useEulerAngle = false); + + void blend(const TransformationMatrix& from, double progress); + + bool isAffine() const + { + return (m13() == 0 && m14() == 0 && m23() == 0 && m24() == 0 && + m31() == 0 && m32() == 0 && m33() == 1 && m34() == 0 && m43() == 0 && m44() == 1); + } + + // Throw away the non-affine parts of the matrix (lossy!) + void makeAffine(); + + bool operator==(const TransformationMatrix& m2) const + { + return (m_matrix[0][0] == m2.m_matrix[0][0] && + m_matrix[0][1] == m2.m_matrix[0][1] && + m_matrix[0][2] == m2.m_matrix[0][2] && + m_matrix[0][3] == m2.m_matrix[0][3] && + m_matrix[1][0] == m2.m_matrix[1][0] && + m_matrix[1][1] == m2.m_matrix[1][1] && + m_matrix[1][2] == m2.m_matrix[1][2] && + m_matrix[1][3] == m2.m_matrix[1][3] && + m_matrix[2][0] == m2.m_matrix[2][0] && + m_matrix[2][1] == m2.m_matrix[2][1] && + m_matrix[2][2] == m2.m_matrix[2][2] && + m_matrix[2][3] == m2.m_matrix[2][3] && + m_matrix[3][0] == m2.m_matrix[3][0] && + m_matrix[3][1] == m2.m_matrix[3][1] && + m_matrix[3][2] == m2.m_matrix[3][2] && + m_matrix[3][3] == m2.m_matrix[3][3]); + } + + bool operator!=(const TransformationMatrix& other) const { return !(*this == other); } + + // *this = *this * t (i.e., a multRight) + TransformationMatrix& operator*=(const TransformationMatrix& t) + { + return multiply(t); + } + + // result = *this * t (i.e., a multRight) + TransformationMatrix operator*(const TransformationMatrix& t) + { + TransformationMatrix result = *this; + result.multiply(t); + return result; + } + + CATransform3D transform3d () const; + CGAffineTransform affineTransform () const; + + TransformationMatrix(const CATransform3D&); + operator CATransform3D() const; + + TransformationMatrix(const CGAffineTransform&); + operator CGAffineTransform() const; + + private: + + // multiply passed 2D point by matrix (assume z=0) + void multVecMatrix(double x, double y, double& dstX, double& dstY) const; + + // multiply passed 3D point by matrix + void multVecMatrix(double x, double y, double z, double& dstX, double& dstY, double& dstZ) const; + + void setMatrix(const Matrix4 m) + { + if (m && m != m_matrix) + memcpy(m_matrix, m, sizeof(Matrix4)); + } + + bool isIdentityOrTranslation() const + { + return m_matrix[0][0] == 1 && m_matrix[0][1] == 0 && m_matrix[0][2] == 0 && m_matrix[0][3] == 0 && + m_matrix[1][0] == 0 && m_matrix[1][1] == 1 && m_matrix[1][2] == 0 && m_matrix[1][3] == 0 && + m_matrix[2][0] == 0 && m_matrix[2][1] == 0 && m_matrix[2][2] == 1 && m_matrix[2][3] == 0 && + m_matrix[3][3] == 1; + } + + Matrix4 m_matrix; + }; + +} // namespace WebCore + +#endif // TransformationMatrix_h diff --git a/Example/Pods/pop/pop/WebCore/UnitBezier.h b/Example/Pods/pop/pop/WebCore/UnitBezier.h new file mode 100644 index 0000000..0f847a0 --- /dev/null +++ b/Example/Pods/pop/pop/WebCore/UnitBezier.h @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2008 Apple Inc. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef UnitBezier_h +#define UnitBezier_h + +#include + +namespace WebCore { + + struct UnitBezier { + UnitBezier(double p1x, double p1y, double p2x, double p2y) + { + // Calculate the polynomial coefficients, implicit first and last control points are (0,0) and (1,1). + cx = 3.0 * p1x; + bx = 3.0 * (p2x - p1x) - cx; + ax = 1.0 - cx -bx; + + cy = 3.0 * p1y; + by = 3.0 * (p2y - p1y) - cy; + ay = 1.0 - cy - by; + } + + double sampleCurveX(double t) + { + // `ax t^3 + bx t^2 + cx t' expanded using Horner's rule. + return ((ax * t + bx) * t + cx) * t; + } + + double sampleCurveY(double t) + { + return ((ay * t + by) * t + cy) * t; + } + + double sampleCurveDerivativeX(double t) + { + return (3.0 * ax * t + 2.0 * bx) * t + cx; + } + + // Given an x value, find a parametric value it came from. + double solveCurveX(double x, double epsilon) + { + double t0; + double t1; + double t2; + double x2; + double d2; + int i; + + // First try a few iterations of Newton's method -- normally very fast. + for (t2 = x, i = 0; i < 8; i++) { + x2 = sampleCurveX(t2) - x; + if (fabs (x2) < epsilon) + return t2; + d2 = sampleCurveDerivativeX(t2); + if (fabs(d2) < 1e-6) + break; + t2 = t2 - x2 / d2; + } + + // Fall back to the bisection method for reliability. + t0 = 0.0; + t1 = 1.0; + t2 = x; + + if (t2 < t0) + return t0; + if (t2 > t1) + return t1; + + while (t0 < t1) { + x2 = sampleCurveX(t2); + if (fabs(x2 - x) < epsilon) + return t2; + if (x > x2) + t0 = t2; + else + t1 = t2; + t2 = (t1 - t0) * .5 + t0; + } + + // Failure. + return t2; + } + + double solve(double x, double epsilon) + { + return sampleCurveY(solveCurveX(x, epsilon)); + } + + private: + double ax; + double bx; + double cx; + + double ay; + double by; + double cy; + }; +} +#endif diff --git a/Example/TabBarPicker.xcodeproj/project.pbxproj b/Example/TabBarPicker.xcodeproj/project.pbxproj index ad156aa..bb12a5a 100644 --- a/Example/TabBarPicker.xcodeproj/project.pbxproj +++ b/Example/TabBarPicker.xcodeproj/project.pbxproj @@ -41,7 +41,7 @@ 237F470FDED70DC43285050F /* Pods_TabBarPicker_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_TabBarPicker_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 307945FB633D00D016BD64BD /* Pods-TabBarPicker_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TabBarPicker_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-TabBarPicker_Tests/Pods-TabBarPicker_Tests.debug.xcconfig"; sourceTree = ""; }; 3956BCE29C077B3AAC271032 /* Pods-TabBarPicker_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-TabBarPicker_Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-TabBarPicker_Example/Pods-TabBarPicker_Example.release.xcconfig"; sourceTree = ""; }; - 6003F58A195388D20070C39A /* TabBarPicker.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; name = TabBarPicker.app; path = TabBarPicker_Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 6003F58A195388D20070C39A /* TabBarPicker_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TabBarPicker_Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 6003F58D195388D20070C39A /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 6003F58F195388D20070C39A /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 6003F591195388D20070C39A /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; @@ -54,7 +54,7 @@ 6003F5A5195388D20070C39A /* TabBarPickerViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TabBarPickerViewController.h; sourceTree = ""; }; 6003F5A6195388D20070C39A /* TabBarPickerViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = TabBarPickerViewController.m; sourceTree = ""; }; 6003F5A8195388D20070C39A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; - 6003F5AE195388D20070C39A /* Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; name = Tests.xctest; path = TabBarPicker_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 6003F5AE195388D20070C39A /* TabBarPicker_Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TabBarPicker_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 6003F5AF195388D20070C39A /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 6003F5B7195388D20070C39A /* Tests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Tests-Info.plist"; sourceTree = ""; }; 6003F5B9195388D20070C39A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; @@ -119,8 +119,8 @@ 6003F58B195388D20070C39A /* Products */ = { isa = PBXGroup; children = ( - 6003F58A195388D20070C39A /* TabBarPicker.app */, - 6003F5AE195388D20070C39A /* Tests.xctest */, + 6003F58A195388D20070C39A /* TabBarPicker_Example.app */, + 6003F5AE195388D20070C39A /* TabBarPicker_Tests.xctest */, ); name = Products; sourceTree = ""; @@ -213,7 +213,7 @@ ); name = TabBarPicker_Example; productName = TabBarPicker; - productReference = 6003F58A195388D20070C39A /* TabBarPicker.app */; + productReference = 6003F58A195388D20070C39A /* TabBarPicker_Example.app */; productType = "com.apple.product-type.application"; }; 6003F5AD195388D20070C39A /* TabBarPicker_Tests */ = { @@ -234,7 +234,7 @@ ); name = TabBarPicker_Tests; productName = TabBarPickerTests; - productReference = 6003F5AE195388D20070C39A /* Tests.xctest */; + productReference = 6003F5AE195388D20070C39A /* TabBarPicker_Tests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; /* End PBXNativeTarget section */ diff --git a/Example/TabBarPicker.xcworkspace/contents.xcworkspacedata b/Example/TabBarPicker.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..e03514f --- /dev/null +++ b/Example/TabBarPicker.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/Example/TabBarPicker/TabBarPickerAppDelegate.m b/Example/TabBarPicker/TabBarPickerAppDelegate.m index 2602cf5..ee75f14 100644 --- a/Example/TabBarPicker/TabBarPickerAppDelegate.m +++ b/Example/TabBarPicker/TabBarPickerAppDelegate.m @@ -7,12 +7,15 @@ // #import "TabBarPickerAppDelegate.h" +#import "TabBarPickerViewController.h" @implementation TabBarPickerAppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. + TabBarPickerViewController * controller = [[TabBarPickerViewController alloc] init]; + return YES; } diff --git a/Example/TabBarPicker/TabBarPickerViewController.m b/Example/TabBarPicker/TabBarPickerViewController.m index 02cc3f6..639e71f 100644 --- a/Example/TabBarPicker/TabBarPickerViewController.m +++ b/Example/TabBarPicker/TabBarPickerViewController.m @@ -7,6 +7,7 @@ // #import "TabBarPickerViewController.h" +#import @interface TabBarPickerViewController () @@ -14,6 +15,39 @@ @implementation TabBarPickerViewController + +- (instancetype) init { + self = [super init]; + + if (self) { + + TabBarSubItem *subItem1 = [TabBarSubItem tabBarSubItemWithName:@"Peppe"]; + TabBarSubItem *subItem2 = [TabBarSubItem tabBarSubItemWithName:@"Peppe1"]; + TabBarSubItem *subItem3 = [TabBarSubItem tabBarSubItemWithName:@"Peppe2"]; + TabBarSubItem *subItem4 = [TabBarSubItem tabBarSubItemWithName:@"Peppe3"]; + TabBarSubItem *subItem5 = [TabBarSubItem tabBarSubItemWithName:@"Peppe4"]; + TabBarSubItem *subItem6 = [TabBarSubItem tabBarSubItemWithName:@"Peppe5"]; + TabBarSubItem *subItem7 = [TabBarSubItem tabBarSubItemWithName:@"Peppe6"]; + + + TabBarItem *item1 = [[TabBarItem alloc] initWithSubItems:@[subItem1,subItem2,subItem3,subItem4,subItem5,subItem6,subItem7]]; + [item1 setItemName:@"PeppeItem"]; + + TabBarItem *item2 = [[TabBarItem alloc] initWithSubItems:@[subItem1,subItem2,subItem3,subItem4,subItem5,subItem6,subItem7]]; + [item2 setItemName:@"PeppeItem1"]; + + TabBarPicker *tabbar = [[TabBarPicker alloc] initWithTabBarItems:@[item1,item2] withSize:CGSizeMake(400, 400) forPosition:TabBarPickerPositionBottom]; + + + + } + return self; +} + +- (void) loadView { + +} + - (void)viewDidLoad { [super viewDidLoad]; diff --git a/Pod/Classes/TabBarItem.h b/Pod/Classes/TabBarItem.h new file mode 100644 index 0000000..c2cee25 --- /dev/null +++ b/Pod/Classes/TabBarItem.h @@ -0,0 +1,41 @@ +// +// TabBarItem.h +// Pods +// +// Created by Giuseppe Nucifora on 15/07/15. +// +// + +#import +#import "TabBarSubItem.h" + +@interface TabBarItem : NSObject + +/** + * Represents the image visible in picker when item is not selected. + */ +@property (nonatomic, strong) UIImage *image; +/** + * Represents the image visible in picker when item is selected. + */ +@property (nonatomic, strong) UIImage *selectedImage; +/** + * Represents the name of the item that can be shown in picker. + */ +@property (nonatomic, strong) NSString *itemName; +/** + * Represents the sub items that appeare when you select the item in picker. + */ +@property (nonatomic, strong) NSMutableArray *subItems; + +/** + * <#Description#> + * + * @param array <#array description#> + * + * @return <#return value description#> + */ +- (instancetype) initWithSubItems:(NSArray*) array; + + +@end diff --git a/Pod/Classes/TabBarItem.m b/Pod/Classes/TabBarItem.m new file mode 100644 index 0000000..19c1864 --- /dev/null +++ b/Pod/Classes/TabBarItem.m @@ -0,0 +1,31 @@ +// +// TabBarItem.m +// Pods +// +// Created by Giuseppe Nucifora on 15/07/15. +// +// + +#import "TabBarItem.h" + +@implementation TabBarItem + +- (instancetype) initWithSubItems:(NSArray*) array { + self = [super init]; + + if (self) { + NSAssert(array, @"SubItemsArray cannot be nil"); + + + _subItems = [[NSMutableArray alloc] init]; + + for (NSObject *subItem in array) { + if ([subItem isKindOfClass:[TabBarSubItem class]]) { + [_subItems addObject:subItem]; + } + } + } + return self; +} + +@end diff --git a/Pod/Classes/TabBarPicker.h b/Pod/Classes/TabBarPicker.h new file mode 100644 index 0000000..55bda6d --- /dev/null +++ b/Pod/Classes/TabBarPicker.h @@ -0,0 +1,41 @@ +// +// TabBarPicker.h +// Pods +// +// Created by Giuseppe Nucifora on 15/07/15. +// +// + +#import +#import "TabbarItem.h" +#import "TabBarSubItem.h" + +typedef enum +{ + // Informational + TabBarPickerPositionLeft, + TabBarPickerPositionRight, + TabBarPickerPositionBottom + +} TabBarPickerPosition; + +@interface TabBarPicker : UIView + + + +@property (nonatomic, strong) NSMutableArray *tabBarItems; +@property (nonatomic) CGFloat maxHeight; +@property (nonatomic) CGFloat maxWidth; +@property (nonatomic) TabBarPickerPosition position; + +/** + * Init TabBarPicker with items. When is selected an item the picher show down subitems. + * By default when one of more subItems are selected the selected item become selected. + * + * @param items Represents tab bar items. That array cannot be nil. + * + * @return raturn instance of TabBarPicker object. + */ +- (instancetype) initWithTabBarItems:(NSArray*) items withSize:(CGSize) size forPosition:(TabBarPickerPosition) position; + +@end diff --git a/Pod/Classes/TabBarPicker.m b/Pod/Classes/TabBarPicker.m new file mode 100644 index 0000000..40eec61 --- /dev/null +++ b/Pod/Classes/TabBarPicker.m @@ -0,0 +1,31 @@ +// +// TabBarPicker.m +// Pods +// +// Created by Giuseppe Nucifora on 15/07/15. +// +// + +#import "TabBarPicker.h" + +@implementation TabBarPicker + +- (instancetype) initWithTabBarItems:(NSArray*) items withSize:(CGSize) size forPosition:(TabBarPickerPosition) position { + + self = [super init]; + if (self) { + + NSAssert(items, @"TabBar Items array cannot be nil!"); + + _tabBarItems = [[NSMutableArray alloc] init]; + + for (NSObject *item in items) { + if ([item isKindOfClass:[TabBarItem class]]) { + [_tabBarItems addObject:item]; + } + } + } + return self; +} + +@end diff --git a/Pod/Classes/TabBarSubItem.h b/Pod/Classes/TabBarSubItem.h new file mode 100644 index 0000000..51defbb --- /dev/null +++ b/Pod/Classes/TabBarSubItem.h @@ -0,0 +1,17 @@ +// +// TabBarSubItem.h +// Pods +// +// Created by Giuseppe Nucifora on 15/07/15. +// +// + +#import + +@interface TabBarSubItem : NSObject + +@property (nonatomic, strong) NSString *name; + ++ (instancetype) tabBarSubItemWithName:(NSString*)name; + +@end diff --git a/Pod/Classes/TabBarSubItem.m b/Pod/Classes/TabBarSubItem.m new file mode 100644 index 0000000..29a1de5 --- /dev/null +++ b/Pod/Classes/TabBarSubItem.m @@ -0,0 +1,28 @@ +// +// TabBarSubItem.m +// Pods +// +// Created by Giuseppe Nucifora on 15/07/15. +// +// + +#import "TabBarSubItem.h" + +@implementation TabBarSubItem + + +- (instancetype) initWithName:(NSString *) name { + + self = [super init]; + + if (self) { + _name = name; + } + return self; +} + ++ (instancetype) tabBarSubItemWithName:(NSString*)name { + return [[self alloc] initWithName:name]; +} + +@end diff --git a/TabBarPicker.podspec b/TabBarPicker.podspec index 6badd0c..fe42b59 100644 --- a/TabBarPicker.podspec +++ b/TabBarPicker.podspec @@ -10,18 +10,13 @@ Pod::Spec.new do |s| s.name = "TabBarPicker" s.version = "0.1.0" - s.summary = "A short description of TabBarPicker." - s.description = <<-DESC - An optional longer description of TabBarPicker - - * Markdown format. - * Don't worry about the indent, we strip it! - DESC - s.homepage = "https://github.com//TabBarPicker" + s.summary = "TabBarPicker." + #s.description = "" + s.homepage = "https://github.com/giuseppenucifora/TabBarPicker" # s.screenshots = "www.example.com/screenshots_1", "www.example.com/screenshots_2" s.license = 'MIT' s.author = { "Giuseppe Nucifora" => "me@giuseppenucifora.com" } - s.source = { :git => "https://github.com//TabBarPicker.git", :tag => s.version.to_s } + s.source = { :git => "https://github.com/giuseppenucifora/TabBarPicker.git", :tag => s.version.to_s } # s.social_media_url = 'https://twitter.com/' s.platform = :ios, '7.0'