From 71a78606039428cc1cd9e79eb96119bcc165f111 Mon Sep 17 00:00:00 2001 From: Dalton Date: Tue, 26 Sep 2017 08:51:50 -0500 Subject: [PATCH] Swift 4 Update --- Example/KeyboardSpy.xcodeproj/project.pbxproj | 30 +- .../xcschemes/KeyboardSpy-Example.xcscheme | 4 +- .../UserInterfaceState.xcuserstate | Bin 31996 -> 31489 bytes Example/KeyboardSpy/KeyboardSpyView.swift | 17 +- Example/Podfile | 12 +- Example/Podfile.lock | 22 +- .../Local Podspecs/KeyboardSpy.podspec.json | 8 +- .../Pods/Local Podspecs/Material.podspec.json | 39 + Example/Pods/Manifest.lock | 22 +- Example/Pods/Material/LICENSE.md | 2 +- Example/Pods/Material/README.md | 161 +- .../Sources/Animator/MotionAnimator.swift | 75 + .../Animator/MotionAnimatorViewContext.swift | 110 + .../MotionCoreAnimationViewContext.swift | 427 ++++ .../Animator/MotionHasInsertOrder.swift | 32 + .../Animator/MotionTransitionAnimator.swift | 158 ++ .../MotionViewPropertyViewContext.swift | 72 + .../Sources/Extensions/Motion+Array.swift | 43 + .../Sources/Extensions/Motion+CALayer.swift | 288 +++ .../Motion+CAMediaTimingFunction.swift | 46 + .../Motion/Sources/Extensions/Motion+CG.swift | 296 +++ .../Sources/Extensions/Motion+Obj-C.swift | 54 + .../Sources/Extensions/Motion+UIKit.swift | 58 + .../Sources/Extensions/Motion+UIView.swift | 257 ++ .../Extensions/Motion+UIViewController.swift | 326 +++ .../Extensions/MotionAnimationFillMode.swift | 51 + .../Frameworks/Motion/Sources/Motion.swift | 853 +++++++ .../Motion/Sources/MotionAnimation.swift | 404 ++++ .../Motion/Sources/MotionAnimationState.swift | 150 ++ .../Motion/Sources/MotionCAAnimation.swift | 317 +++ .../Motion/Sources/MotionContext.swift | 486 ++++ .../Motion/Sources/MotionController.swift | 563 +++++ .../Sources/MotionCoordinateSpace.swift | 35 + .../Sources/MotionIndependentController.swift | 68 + .../Motion/Sources/MotionPlugin.swift | 153 ++ .../Motion/Sources/MotionSnapshotType.swift | 52 + .../Motion/Sources/MotionTransition.swift | 568 +++++ .../Sources/MotionTransitionObserver.swift | 38 + .../Sources/MotionTransitionState.swift | 208 ++ .../Preprocessors/CascadePreprocessor.swift | 114 + .../Preprocessors/DurationPreprocessor.swift | 93 + .../IgnoreSubviewModifiersPreprocessor.swift | 81 + .../Preprocessors/MatchPreprocessor.swift | 89 + .../Preprocessors/MotionPreprocessor.swift | 41 + .../Preprocessors/SourcePreprocessor.swift | 121 + .../TransitionPreprocessor.swift | 390 ++++ .../Material/Sources/iOS/Application.swift | 13 +- Example/Pods/Material/Sources/iOS/Bar.swift | 31 +- .../Pods/Material/Sources/iOS/Border.swift | 54 +- .../iOS/BottomNavigationController.swift | 103 +- .../Material/Sources/iOS/BottomTabBar.swift | 133 -- .../Pods/Material/Sources/iOS/Button.swift | 26 +- Example/Pods/Material/Sources/iOS/Card.swift | 23 +- ...ler.swift => CardCollectionViewCell.swift} | 56 +- .../iOS/CardCollectionViewController.swift | 138 ++ .../Sources/iOS/CharacterAttribute.swift | 24 +- .../Pods/Material/Sources/iOS/ChipBar.swift | 378 +++ .../Sources/iOS/ChipBarController.swift | 146 ++ .../Sources/iOS/CollectionReusableView.swift | 25 +- .../Material/Sources/iOS/CollectionView.swift | 25 +- .../Sources/iOS/CollectionViewCell.swift | 27 +- .../iOS/CollectionViewController.swift | 24 +- .../Sources/iOS/CollectionViewLayout.swift | 239 +- Example/Pods/Material/Sources/iOS/Color.swift | 2 +- .../Material/Sources/iOS/CornerRadius.swift | 2 +- .../Material/Sources/iOS/DataSourceItem.swift | 2 +- Example/Pods/Material/Sources/iOS/Depth.swift | 13 +- .../Pods/Material/Sources/iOS/Device.swift | 15 +- .../iOS/{Display.swift => DisplayStyle.swift} | 6 +- .../Pods/Material/Sources/iOS/Divider.swift | 13 +- .../Sources/iOS/DynamicFontType.swift | 4 +- .../Material/Sources/iOS/EdgeInsets.swift | 68 +- .../Pods/Material/Sources/iOS/Editor.swift | 381 --- .../Material/Sources/iOS/ErrorTextField.swift | 9 +- .../Pods/Material/Sources/iOS/FABMenu.swift | 473 ++++ .../Sources/iOS/FABMenuController.swift | 217 ++ .../Pods/Material/Sources/iOS/FabButton.swift | 11 +- .../Material/Sources/iOS/FlatButton.swift | 9 +- Example/Pods/Material/Sources/iOS/Font.swift | 6 +- .../Pods/Material/Sources/iOS/Gravity.swift | 2 +- Example/Pods/Material/Sources/iOS/Grid.swift | 9 +- .../Material/Sources/iOS/HeightPreset.swift | 3 +- Example/Pods/Material/Sources/iOS/Icon.swift | 4 +- .../Material/Sources/iOS/IconButton.swift | 11 +- .../Pods/Material/Sources/iOS/ImageCard.swift | 22 +- .../Material/Sources/iOS/InterimSpace.swift | 2 +- Example/Pods/Material/Sources/iOS/Layer.swift | 2 +- .../Pods/Material/Sources/iOS/Layout.swift | 38 +- .../Material/Sources/iOS/Material+Array.swift | 4 +- .../Sources/iOS/Material+CALayer.swift | 89 +- ...C.swift => Material+MotionAnimation.swift} | 51 +- .../Sources/iOS/Material+String.swift | 2 +- .../Sources/iOS/Material+UIFont.swift | 14 +- .../Sources/iOS/Material+UIImage.swift | 30 +- .../Sources/iOS/Material+UIView.swift | 45 +- ....swift => Material+UIViewController.swift} | 72 +- .../Sources/iOS/Material+UIWindow.swift | 2 +- Example/Pods/Material/Sources/iOS/Menu.swift | 613 ----- .../Material/Sources/iOS/MenuController.swift | 129 - .../Pods/Material/Sources/iOS/MenuItem.swift | 106 - .../Pods/Material/Sources/iOS/Motion.swift | 187 -- .../Material/Sources/iOS/MotionBasic.swift | 423 ---- .../Sources/iOS/MotionTransition.swift | 107 - .../Material/Sources/iOS/NavigationBar.swift | 18 +- .../Sources/iOS/NavigationController.swift | 24 +- .../iOS/NavigationDrawerController.swift | 368 +-- .../Material/Sources/iOS/NavigationItem.swift | 52 +- .../Pods/Material/Sources/iOS/Offset.swift | 2 +- .../Sources/iOS/PageTabBarController.swift | 355 --- .../Material/Sources/iOS/PresenterCard.swift | 4 +- ...MotionPulse.swift => PulseAnimation.swift} | 40 +- .../Pods/Material/Sources/iOS/PulseView.swift | 32 +- .../Material/Sources/iOS/RaisedButton.swift | 9 +- .../Material/Sources/iOS/RobotoFont.swift | 2 +- .../Pods/Material/Sources/iOS/Screen.swift | 2 +- .../Pods/Material/Sources/iOS/SearchBar.swift | 38 +- .../Sources/iOS/SearchBarController.swift | 119 +- Example/Pods/Material/Sources/iOS/Shape.swift | 2 +- .../Pods/Material/Sources/iOS/Snackbar.swift | 28 +- .../Sources/iOS/SnackbarController.swift | 22 +- .../Sources/iOS/SpringAnimation.swift | 477 ++++ .../Sources/iOS/StatusBarController.swift | 69 +- .../Pods/Material/Sources/iOS/Switch.swift | 56 +- .../Pods/Material/Sources/iOS/TabBar.swift | 366 ++- .../Pods/Material/Sources/iOS/TableView.swift | 45 +- .../Material/Sources/iOS/TableViewCell.swift | 30 +- .../Sources/iOS/TableViewController.swift | 2 +- .../Material/Sources/iOS/TabsController.swift | 408 ++++ .../Pods/Material/Sources/iOS/TextField.swift | 468 ++-- .../Material/Sources/iOS/TextStorage.swift | 2 +- .../Pods/Material/Sources/iOS/TextView.swift | 589 +++-- .../Pods/Material/Sources/iOS/Toolbar.swift | 22 +- .../Sources/iOS/ToolbarController.swift | 231 +- ...oller.swift => TransitionController.swift} | 177 +- Example/Pods/Material/Sources/iOS/View.swift | 2 +- Example/Pods/Pods.xcodeproj/project.pbxproj | 2075 +++++++++-------- .../xcschemes/KeyboardSpy.xcscheme | 41 +- ...al-com.cosmicmind.material.fonts.xcscheme} | 41 +- ...al-com.cosmicmind.material.icons.xcscheme} | 41 +- .../xcschemes/Material.xcscheme | 41 +- .../Pods-KeyboardSpy_Example.xcscheme | 8 +- .../xcschemes/SnapKit.xcscheme | 41 +- .../xcschemes/xcschememanagement.plist | 37 +- Example/Pods/SnapKit/README.md | 14 +- Example/Pods/SnapKit/Source/Constraint.swift | 103 +- .../SnapKit/Source/ConstraintAttributes.swift | 4 +- .../Source/ConstraintConstantTarget.swift | 2 +- .../Pods/SnapKit/Source/ConstraintDSL.swift | 4 +- .../SnapKit/Source/ConstraintInsets.swift | 2 +- .../Source/ConstraintMakerExtendable.swift | 6 + .../Source/ConstraintMakerPriortizable.swift | 27 +- .../SnapKit/Source/ConstraintPriority.swift | 77 + .../SnapKit/Source/ConstraintRelation.swift | 2 +- .../SnapKit/Source/ConstraintViewDSL.swift | 16 +- Example/Pods/SnapKit/Source/Debugging.swift | 6 +- Example/Pods/SnapKit/Source/Typealiases.swift | 37 + .../KeyboardSpy/Info.plist | 2 +- .../KeyboardSpy/KeyboardSpy-prefix.pch | 8 + .../KeyboardSpy/KeyboardSpy-umbrella.h | 8 + .../KeyboardSpy/KeyboardSpy.xcconfig | 1 + .../Target Support Files/Material/Info.plist | 2 +- .../Material/Material-prefix.pch | 8 + .../Material/Material-umbrella.h | 8 + .../Material/Material.xcconfig | 1 + ...e-com.cosmicmind.material.fonts-Info.plist | 24 + ...e-com.cosmicmind.material.icons-Info.plist | 24 + ...boardSpy_Example-acknowledgements.markdown | 2 +- ...KeyboardSpy_Example-acknowledgements.plist | 2 +- .../Pods-KeyboardSpy_Example-frameworks.sh | 45 +- .../Pods-KeyboardSpy_Example-resources.sh | 28 +- .../Pods-KeyboardSpy_Example-umbrella.h | 8 + .../Pods-KeyboardSpy_Example.debug.xcconfig | 2 +- .../Pods-KeyboardSpy_Example.release.xcconfig | 2 +- .../Target Support Files/SnapKit/Info.plist | 2 +- .../SnapKit/SnapKit-prefix.pch | 8 + .../SnapKit/SnapKit-umbrella.h | 8 + .../SnapKit/SnapKit.xcconfig | 1 + KeyboardSpy.podspec | 2 +- KeyboardSpy/Classes/KeyboardSpy.swift | 12 +- KeyboardSpy/Classes/KeyboardSpyAgent.swift | 2 +- README.md | 28 +- 181 files changed, 13412 insertions(+), 5609 deletions(-) create mode 100644 Example/Pods/Local Podspecs/Material.podspec.json create mode 100644 Example/Pods/Material/Sources/Frameworks/Motion/Sources/Animator/MotionAnimator.swift create mode 100644 Example/Pods/Material/Sources/Frameworks/Motion/Sources/Animator/MotionAnimatorViewContext.swift create mode 100644 Example/Pods/Material/Sources/Frameworks/Motion/Sources/Animator/MotionCoreAnimationViewContext.swift create mode 100644 Example/Pods/Material/Sources/Frameworks/Motion/Sources/Animator/MotionHasInsertOrder.swift create mode 100644 Example/Pods/Material/Sources/Frameworks/Motion/Sources/Animator/MotionTransitionAnimator.swift create mode 100644 Example/Pods/Material/Sources/Frameworks/Motion/Sources/Animator/MotionViewPropertyViewContext.swift create mode 100644 Example/Pods/Material/Sources/Frameworks/Motion/Sources/Extensions/Motion+Array.swift create mode 100644 Example/Pods/Material/Sources/Frameworks/Motion/Sources/Extensions/Motion+CALayer.swift create mode 100644 Example/Pods/Material/Sources/Frameworks/Motion/Sources/Extensions/Motion+CAMediaTimingFunction.swift create mode 100644 Example/Pods/Material/Sources/Frameworks/Motion/Sources/Extensions/Motion+CG.swift create mode 100644 Example/Pods/Material/Sources/Frameworks/Motion/Sources/Extensions/Motion+Obj-C.swift create mode 100644 Example/Pods/Material/Sources/Frameworks/Motion/Sources/Extensions/Motion+UIKit.swift create mode 100644 Example/Pods/Material/Sources/Frameworks/Motion/Sources/Extensions/Motion+UIView.swift create mode 100644 Example/Pods/Material/Sources/Frameworks/Motion/Sources/Extensions/Motion+UIViewController.swift create mode 100644 Example/Pods/Material/Sources/Frameworks/Motion/Sources/Extensions/MotionAnimationFillMode.swift create mode 100644 Example/Pods/Material/Sources/Frameworks/Motion/Sources/Motion.swift create mode 100644 Example/Pods/Material/Sources/Frameworks/Motion/Sources/MotionAnimation.swift create mode 100644 Example/Pods/Material/Sources/Frameworks/Motion/Sources/MotionAnimationState.swift create mode 100644 Example/Pods/Material/Sources/Frameworks/Motion/Sources/MotionCAAnimation.swift create mode 100644 Example/Pods/Material/Sources/Frameworks/Motion/Sources/MotionContext.swift create mode 100644 Example/Pods/Material/Sources/Frameworks/Motion/Sources/MotionController.swift create mode 100644 Example/Pods/Material/Sources/Frameworks/Motion/Sources/MotionCoordinateSpace.swift create mode 100644 Example/Pods/Material/Sources/Frameworks/Motion/Sources/MotionIndependentController.swift create mode 100644 Example/Pods/Material/Sources/Frameworks/Motion/Sources/MotionPlugin.swift create mode 100644 Example/Pods/Material/Sources/Frameworks/Motion/Sources/MotionSnapshotType.swift create mode 100644 Example/Pods/Material/Sources/Frameworks/Motion/Sources/MotionTransition.swift create mode 100644 Example/Pods/Material/Sources/Frameworks/Motion/Sources/MotionTransitionObserver.swift create mode 100644 Example/Pods/Material/Sources/Frameworks/Motion/Sources/MotionTransitionState.swift create mode 100644 Example/Pods/Material/Sources/Frameworks/Motion/Sources/Preprocessors/CascadePreprocessor.swift create mode 100644 Example/Pods/Material/Sources/Frameworks/Motion/Sources/Preprocessors/DurationPreprocessor.swift create mode 100644 Example/Pods/Material/Sources/Frameworks/Motion/Sources/Preprocessors/IgnoreSubviewModifiersPreprocessor.swift create mode 100644 Example/Pods/Material/Sources/Frameworks/Motion/Sources/Preprocessors/MatchPreprocessor.swift create mode 100644 Example/Pods/Material/Sources/Frameworks/Motion/Sources/Preprocessors/MotionPreprocessor.swift create mode 100644 Example/Pods/Material/Sources/Frameworks/Motion/Sources/Preprocessors/SourcePreprocessor.swift create mode 100644 Example/Pods/Material/Sources/Frameworks/Motion/Sources/Preprocessors/TransitionPreprocessor.swift delete mode 100644 Example/Pods/Material/Sources/iOS/BottomTabBar.swift rename Example/Pods/Material/Sources/iOS/{EditorController.swift => CardCollectionViewCell.swift} (53%) create mode 100644 Example/Pods/Material/Sources/iOS/CardCollectionViewController.swift create mode 100644 Example/Pods/Material/Sources/iOS/ChipBar.swift create mode 100644 Example/Pods/Material/Sources/iOS/ChipBarController.swift rename Example/Pods/Material/Sources/iOS/{Display.swift => DisplayStyle.swift} (93%) delete mode 100644 Example/Pods/Material/Sources/iOS/Editor.swift create mode 100644 Example/Pods/Material/Sources/iOS/FABMenu.swift create mode 100644 Example/Pods/Material/Sources/iOS/FABMenuController.swift rename Example/Pods/Material/Sources/iOS/{Material+Obj-C.swift => Material+MotionAnimation.swift} (59%) rename Example/Pods/Material/Sources/iOS/{MotionKeyframe.swift => Material+UIViewController.swift} (55%) delete mode 100644 Example/Pods/Material/Sources/iOS/Menu.swift delete mode 100644 Example/Pods/Material/Sources/iOS/MenuController.swift delete mode 100644 Example/Pods/Material/Sources/iOS/MenuItem.swift delete mode 100644 Example/Pods/Material/Sources/iOS/Motion.swift delete mode 100644 Example/Pods/Material/Sources/iOS/MotionBasic.swift delete mode 100644 Example/Pods/Material/Sources/iOS/MotionTransition.swift delete mode 100644 Example/Pods/Material/Sources/iOS/PageTabBarController.swift rename Example/Pods/Material/Sources/iOS/{MotionPulse.swift => PulseAnimation.swift} (82%) create mode 100644 Example/Pods/Material/Sources/iOS/SpringAnimation.swift create mode 100644 Example/Pods/Material/Sources/iOS/TabsController.swift rename Example/Pods/Material/Sources/iOS/{RootController.swift => TransitionController.swift} (58%) rename Example/Pods/Pods.xcodeproj/xcuserdata/Dalton.xcuserdatad/xcschemes/{Material-io.cosmicmind.material.icons.xcscheme => Material-com.cosmicmind.material.fonts.xcscheme} (61%) rename Example/Pods/Pods.xcodeproj/xcuserdata/Dalton.xcuserdatad/xcschemes/{Material-io.cosmicmind.material.fonts.xcscheme => Material-com.cosmicmind.material.icons.xcscheme} (61%) create mode 100644 Example/Pods/SnapKit/Source/ConstraintPriority.swift create mode 100644 Example/Pods/SnapKit/Source/Typealiases.swift create mode 100644 Example/Pods/Target Support Files/Material/ResourceBundle-com.cosmicmind.material.fonts-Info.plist create mode 100644 Example/Pods/Target Support Files/Material/ResourceBundle-com.cosmicmind.material.icons-Info.plist diff --git a/Example/KeyboardSpy.xcodeproj/project.pbxproj b/Example/KeyboardSpy.xcodeproj/project.pbxproj index c106e89..12c5d0b 100644 --- a/Example/KeyboardSpy.xcodeproj/project.pbxproj +++ b/Example/KeyboardSpy.xcodeproj/project.pbxproj @@ -147,7 +147,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0720; - LastUpgradeCheck = 0820; + LastUpgradeCheck = 0900; ORGANIZATIONNAME = CocoaPods; TargetAttributes = { 607FACCF1AFB9204008FA782 = { @@ -193,13 +193,16 @@ files = ( ); inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", ); name = "[CP] Check Pods Manifest.lock"; outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-KeyboardSpy_Example-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; 52031FEBB41A01DF170CFF16 /* [CP] Copy Pods Resources */ = { @@ -223,9 +226,16 @@ files = ( ); inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-KeyboardSpy_Example/Pods-KeyboardSpy_Example-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/KeyboardSpy/KeyboardSpy.framework", + "${BUILT_PRODUCTS_DIR}/Material/Material.framework", + "${BUILT_PRODUCTS_DIR}/SnapKit/SnapKit.framework", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/KeyboardSpy.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Material.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SnapKit.framework", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -267,14 +277,20 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; @@ -314,14 +330,20 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; @@ -358,7 +380,7 @@ MODULE_NAME = ExampleApp; PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 4.0; }; name = Debug; }; @@ -374,7 +396,7 @@ MODULE_NAME = ExampleApp; PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.$(PRODUCT_NAME:rfc1034identifier)"; PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 4.0; }; name = Release; }; diff --git a/Example/KeyboardSpy.xcodeproj/xcshareddata/xcschemes/KeyboardSpy-Example.xcscheme b/Example/KeyboardSpy.xcodeproj/xcshareddata/xcschemes/KeyboardSpy-Example.xcscheme index 7d585aa..ee6808f 100644 --- a/Example/KeyboardSpy.xcodeproj/xcshareddata/xcschemes/KeyboardSpy-Example.xcscheme +++ b/Example/KeyboardSpy.xcodeproj/xcshareddata/xcschemes/KeyboardSpy-Example.xcscheme @@ -1,6 +1,6 @@ OppXc&;%nZla*KbP1pAr+YMb+eul5-K8sh#@q@B%*?-B&vvNqK2p? zrVw>RJ)tEU2p!Q#G!gB@ErfxXMchivCT=6<5VsQov4psrxRS)f!Ijw zBAy|36MKkfiRXyD#6jXk;x*!R;tk>?@eXl{c$fH)_>B0P_<{J5_=)(PxP(~5AsMnl z*2n>kK`tl&1)?Anj6zT-nt;Mk4AP)j6o)3E$tV@2p>&ji8c`E!MtanOT2UKnN4KD< zr~`GPZq$SN&@40;-GvsSMQAZvf>xlF=zjDN+KjfKN6}Wa4LydoqbJcWbP&CWUP14n z)952~4tX!$~+9r{GLniYswF*5U@- zgqyJ*Ps4q97QPkF#<%0Sn8yM-f#=~n@DhACUW!-X2k;=?fH&gp_({A2@5RsKL-=KU z7=M62#2?|0@mc%{{uFU9P^Qb$hd#PpAa_T;61+|)5Lp@AALanEsq;^nGQ9G%psa@1F z)NX1I^*ptYI!L`py+$3S-l9%WC#kd4C)B6ZXVf|BbLv~_N9s@N5_OqoXqL97?ddVJ z3++jJ(F)p|_Mrpm7+OQe(s6V=olIxYMRYM;OHZNeXdT@`x6%f>o1RAZ&@<^-^sV&m z^m=*&y^(&D-bz0~Z>M+CPt$woXX$iFCHfWm2>k~ACVh-PPM@ORrO(hG&}ZpS z=+Egd=x^w6>EG##^dIz}^ddZvYGWsFQO)5lC_<}r6LcQW&t<;;D|3T7pm_cSc z^CYu_d5YQ3yuch_4l-{tN13;nx0zGS`^*{U6XsLq3+8*~XXZEN5^Kvku#T(?>&kkt z<5&gj&HA$etcHzcbJ$$Aj;&|4Yy+!f8`&ndnbotMY!_=_ zyV+@M4{K!SvkTa}*oEvOb}_qzy_;Ri-p{ULSF>x_2iR@wW9;MX6YO^ONp=VO6uXn% z%RbNUWB0Q!ptI}&_BeZjJ;}bqo?_o+-(yd+pRk{@pRpI%-`L;Ti|illpX?>}GDmSV z$8apiaqgT4H;x<6d2(Kyg7fBlxDYOso4|!};oL+{$*H&qPQ%4=aa;jc$Q5zLTnSgo zm2u@<1y{*can)Q6SIbT13|u$Y%k^=yxLdi~xw+gO+@0J)ZV|VfyN_GJt>o_K9^xM6 zHgTJ|?c9^x4(=)LIqpU74em|uDEAikF82xdDfbz7j{BVZg8P#DiTj!Rh5MDe!d;aS zGAo(2%uePh^O7lK-ZCFqfGk)RA`6vGkSS%+vN&0$ELWB%E0PtL`*rnobete$gcV^; z*bw%FV`V{U_*DHYV-5T^>+cG`rVgFaI6&AEc0A_E0YXkV@RWd}_#my^FEv>eql!$` zgk`AH)nV$C2xVAoT1skIv|5v@)ymIdM%h; z2rnXN3*kzPCEN&i!h;w`j3+#KnrC>H=Xe=!#ar_>TL=Z=P53}J+z5XnfC%Jmc{|<# zy2J`7k{{1!@e}GrH0@o@h8Y<>x=y`T?hOwLdz$q<`sN|@WxB>xLsxH)p`!zqDy@9d z$i9s#)J8_6q{Kua=n< zv8rjrWd=h>qpm00SkZ25he}%c*x@o=W6G!^x7o9!R1*}D%Gfy*6th)Ps^|#{l`=YF z&Ya^WVTdH62M9Ic#@ho61SxSgkK)OTp*a`;x-W|&c+o8I2413GKvF3CnC7&*GG-t^{n zcw)@c%`)`$YUN=fT`j^qN?^)++dJBOXC?ROb){e-^;Wd&XGpMz;EH8hxl_Kr)6g?3 zvq#t6mZop)Yi$)JW0W9`0-UBdwzqbTf;&Y7KHSza0I3V@dSe~*QtG%FWv+f!qe0ix zT-rS=yxY)h?AABQx+Do?pi~LeS}i9`$TdBlPn;$CFJ9l{6s zCUw6(0@zaGp8A5){JvgsHkpKPkXR~;pM+}}u^d=5RACtDAhB#D+7-kDM9@ZJC2>Eo zidapo;luffypmV(5gUoM#5&?Z;vwQ;K9bMnOZjGAFVa*|)nsVahXZeN+k3-@q$0eu zx2LbEx334Lt;bEOl)?Ph%E#TL)FcVOvr>HrSl#;OA<$a+_?tAzHX8f%Mhgu$5swo= zn~2TC7UEH2E3u7uj92qfd^8`!Yxvkr#1q7J;z^iJPl4u*<5T!lm`2&6(v`G(`pj-! zSF^s^BqwD(dcCNN&8nybdZd-x!vjn2#0oGL@kwgFsLuL~8SNdt`kwZ#*7PosE6vh$ z7#hYX_$m4pLyvx_g#=C1^?(T!t!053s$d3b8S3-Ie!{Vz*vH5B6EE-y;yNaFu0q!V z^hh>};4D>NA`TNl1H>WXWj>LgG(fyU9N{PPNuWMPOsBFUm`;`!ZxU~dEshXxLA7M@ z!x8uZEsC^q*YugX&h8Gq0=lml0RTuid$w|dLMdwFh^W{JirDCwIdd!^-y_~1>hBpo zjSsREd_?|Ee_I&YB$B`p)k~;qP3_z~P6XpgQi`l^1EEd&OnpMl)y5zoD5e1j|HaM9^a>3uU7ml#B9EJ}N+ks0bCK5@HMA!ng8md^>*& zKb7y`JNYi&z<2XekD+o@fhyr=wP_lZ1BvTlIyCUpcq88nKkqV4i)ldgXW`RxBHbi~kX3%DOkPY#fh0c-&ml$MGt&-e;1~u0mYF{?1TYM%;ou$1fQyr4M1tp@W zruXz1dal)*(kzv9>-A-hBRiSdW9aJ!SSHmD(r1x+eY0s2n9OpMtcs#(OqnHiN*a^- z0SI+(d#7Gve-|>W=X)e3r=V#AB3GpnBT8J)>!i=qiLQP$gYV-*rSG>AU4v*gx(&_Y zr}MM<+lOov#G^Y1#{ndudHf81<^Z}A&F5$FxAH+H?ad{-f3+f??(KFd7gi<|Al5 z>gRc0;O7mZL9_vFWw{ zJ>(bh^Ta-GK+mInXg_*^U(DajKf=SB0NiahJA8SDCY?C#B|8$m1WpDzgkI*C@b~cY z_t6pbDtZmQj@}@w(VOTfdJDacj-lh|IMIkspp)nwbPE2zTWbMVUXlm1+1RV=krZ1; zUuRcAUuUCeN;~SinoZhn?Vq4#>9N^{dz##PAoO_^)%^?rrMT= zp(bNiTDPTX^FBHwt|t{`W%`*zhLMF4gXjbFA(43V3ZQkNsil{eW;bWmS@g+BRsj`~ zLy)a{%h@h4%lex1S zq^L(xVCZdc0==mMVNwK2Yi3Zh-q_UB-UuQb7aS-~a3j?1YSJru+hB^%(DjJMf_eI4 zYb?JJ&9MV^L_cF^{sI0Wp!vgQnqya>IUbAM__h3lH=#KmcLSQQ6UXxZ8*)PzuP3*u zizdm!{$_HA74;aVw>Rq*Iz_X-Mc3EStC%kO1|m^)(+%y-qeu#of@|1QDbZRh?~qud zXcz6TZbOGj(I~om49$Hob4}pE_Xi{*=ekAJXz~nnT?&Kgo32Ab9It2wq!4{jbn2lH zy3whdYG$l{CPW&V+IuHkSR0C!H)O2}N8m`T<_Gvq{BC}ag|#t6bU)VcgEwPqJZ!d@ z{-TpO5l@2ullcvx*fjh`2l~8L-uxd>Y$KK3h|i)oBIz>UU&LbjtPp!zFtxI zdJRp64n>cCT3~&mg*JCi7YJ3iI@!8k!}i5S;s}lA#i_>zC1E=o~U_Euing%PiqPyqtf* z!s3-+O5^+SD!iIMz`w*F9-eG#@x#}K-0&kr0Pg1xf(P@WXc3Dc$ssRR3_?N_F3A*y zvtZqXw_XQi8vuEnKLkKthM1w~l9-~eQu`I_N40+nKXYCC-9#XC;uRpwP$!0Bq9PCr z?tS=xNX-5C1^!k3wE>7!igC*EqQUAlM6wZ%v#5-QTqTd88s-q!h*ArJSMV_+=uvzG zzlvYOuj4oHoA@Yx3%||3!N18L<=^7p=8y5m`4jxfNAYoR$HlmHK7JR!hfhOS-r>K5 z&Uo^k0&*5muz*6uzSVS?V$f2+%Vmf-rq}>DSY6E!-xX;lc2A-kh*X8NBQJd~?Q84= zudhb>CIuCophcRr(3#wJDPXKHKPnQN8^sVriC&Cgzz4~S2fJ7D^7TDKVPeto0Nj@6 zBBYb}3;ZSiim=9Cqf_`>{2dt4JqAOs6iye1QeX;gxWW`@?=wmrGs)`AUa4ekcTamK z#C)$S;y>dF{uKYkDf~VD0TBF%f5JZllCSXv*zEp|Xsm+F15@;&qFVF9*pEwl19rEqPC~KNQ z1Q$Lum4`yeCUr-WMD!p@ku=Hh@ADtL1I`o2Y8q;1VGu5wc^_)G|0oiRBL zq&*3HKB5ahOc=?MG1V;6wf78=4x-=iw{> zKbgpXEvjgLNf(&6$mZ`%K?7Nvnf>s|Ti3O&O zbT^BNx?5a> zGsv0bEb>@Df6AGWN#y=~GevWAFW&&wUiQd}DZWczO|4q-!Uqqv_cvD+eY;YIpZow3h2 zOsW&)bA&ay7o8&ak>kW%mqwjYUkkr`^rCM*UC$E&a^TNOD(wJy5VjCNa0kc(=D0Hn zG0T4Pkbs=TtcWqgn|7**C`h5uL=ErSkw?fk!J8sqC0`?7C*Kgz7y-Em$W=gNH;_k3 zaZx-bAU6Sd@y`kKl&=4hklWr|CO$0MC z3RBFrjVYE0pkxB_7aIrgLBpi=O(gI!P6LNkw}SBMKE#25t_B# zu>E(!Uhd%N>~ixQxPB*|>mS358f~nbgS*E#SVm!wu?bw5E@^I-muII*mNK9oT~ykB zt6s`wgRHrfXjO8WI$0H#s*X(!%Sh3rgr%v)q^Z=DeF|g(L_<=5O08DT zIj->b@x4*@6y&jt?7)DJ-*5_5K%hfVa0s{=1*Ou^rA|tp%^7lDqsvCZGSx6;+1Ue( zn`Vr`Y#-KxmM*J65kjBCCqn;5;vNY1gU70f(YZV-KhrL4W23UEF(y_Sr34`?D1~T> zzF9I;^gSQT?W1Efv2pPUiIXNLC8wl9YCvXIc20I)enDYTaY<>N1(B)Sz{IllUNH;K z0c1t$K?&^PK-x$TBsYTfo6-ZWJ5O?tum8kO7^YCZWyj={Dhk9%MJq9HNf2 z(ZnO3kJDR>?-*?%H_AubS?A#Gs-3Wt6D2viN3=~K~k$V0yeEk|o%({3O781`yDL!U!_ zxjST)hhr6Flc(YgT#j4uLJ0XhjGw~$AS3(@{0{yK|4Oo?6B$gZ$wV@bEFg=_S>6?7 zC77zUV4-SB9hjqflcs>Ib?G-zX8vvdMYah@ZCYNbWGV%CX5O_Ivl$2BQ7VxLyb!-x z)Mz?Y1POpt29-%=QQ1@ul}qJO`BVW_D4=Ko#Rv$LSFC{I1Qaiz1OX)qXp(>?Zw0kh zLX}cwR5?{aRZ>+{HB}?(xFi8j6>yh;Zxiqu0q+s;vjW~L-~*yMc20qa#nf&CMC^^G zBuy~%Ar;Bp919s?LK`y-JzyIcr%1V+QVt6MkiNn;HY|v+FKLP$KsLrG045O?6@nRt zR<6v`8GFUe@(w*99QJ1NkErGO2&+`%uIo_7D)b0>4SibzUNv~trTXal%6=$($qc@ zwqnF%B&B`b;;64}HmZ(R9xw{$=%I!Wn}Oil{$0g9L#u_f7D~*bW{XSrtpdvEr*0Dv zq`i%>B`LvVHwq|ID~BZCf4t8-B8)syWPNxC#Efr&onHv|h$>7Xl%;QXQj5Uyqvlf! zsJp0z0?HOpj(~Cnl(&IeOf97Drj`mQAHE6*ri_$yWnnm^p~80gu)7ArV9p=}X9-9z z?t;N?x^H&MFoTBTOrqsCyn4bikevdX57Tufi*mTYWb{!h!EmPT7f=B&ubJ8w8`hW| z)@&@bjNt)lok-uc0xIgK9u!cqC_!%GoXG7m%;+lY>lM8t5n*L}b8j02lFynHilu!& zwFMHir~zt_+CXijHc^`eR4Sk{0hJ4=LO_)Qs@g<7N^PaKQIAoN6M+J%7Eq0VY6Vm$ zpn5QkC)Cs!44oOeCLnNaD$E^yPm!nwU~^m)B*;NCbmxhi^k$l+0j>O`fN*wNnPI4} z5($b7M#zaWbmi;10f1PTET%VtI?xZJ5o3b->9CUv$=T*OvhU;{B~4j7J1Pp+{s?t= zl$4WAJu6c1IRQ-p3Qn)83G0{{);7J#LV^9%3zD_zJNa!1f~DjoN=#v-4pA=)s6jxD z1Jo1G zDF2J*XqhDACY3_lz=WV7QefoeCuun(3_y-6fl7JVH>-Bz7_+70LG(mX;ekZcq10(Qj1IR*HLOlxW6crJ?VD&N zt)e67NLo!t323f>cmXXC&|Lz$M?lL(DZi0$S){y7*VC#upM5Y3`Hd!pS#nM5I;2~Q zsaWPc9Lsua8KGICB>^1?9aO#a@CHCE15ThP4aqG%SwMnWZs`<|TRN2ngJhn7?i`X^ zI+M=5R=y~ZTe`q3w|9sFrcW9vlXMAPacvuuOjb)WIbUqD>{nA0@b9i4h$NTwqFjP8 zv~Z+cHquShaT>Pr77J*RfSN4Q_@=7G)iTC58us4@Xg3=4&ou{)z%IVqk zZPEm^fSya=O9X9~+tWNP(DUd!=sW58^aA=WdLg}tUQ92c@1~d1AZ!q7gtdRQfF2Og zIsrW-phpDMFQ7pIL7)&8>qiB&O+b$eXuAk)8NHmok6uBqr0=I!(W~h-^aJ!-dL8{B z{Sf`IfOZJzSpn@6&=K=!lc7D_fM-Q6UoRwO+ z?jNiQ)g5yF%g9O*318n$w{qG-AkNj&h@+Yxd zMlHEU^mp`6;2P2A>F?-K!y_#xX^pW!934T0H8U~)IIN2RwV+BiB`?2kdEP* z?Hk69fdgVUrViuGa1y}%BCHVr=OygcS^#)3ikkxPW_$pEpMVYs=%5JTMN^M*Ki<{6 zb%CizDs|MHs@bXtI1s3`43Y_9!1Uk1gfbJDFb2&2LjnTN{;+^v*}y0n6@ZKs&=CQ> zDuR6N|0&1v+k<`z95-dQDkfG9OpA?*0;WYpXd*_ACy`0H>3C9^G#F2YfZh<$o8owm znn;x2o)b5Fpk}rz5-1Z5qEIzk9RcUrhl!NO6yFqR2~!F{IRU*bpku>~%Wtec^3@)* zP^pH5im73=HwD$e=p;}l1axu)sLT)KJH9uuFhV^Hsf~en>P+F+f0-N;OI#W-wrt-vsO&=5_!Je&727IwOMpKmywqmRofY z7^6~(Q6{B2a*p^#6f~7m6+0wr3z#K01${TO6hPlAAc&oOEP_63>G7-FfNAU!XQDNl zk({}oS$k8E>zD@tBv|;L3g|Ntk`P5kMh$_Dh)@rKeUW+PreKdSuL4-`XucQF4^|m8bcFeefn-qPN9HsGM+oF_h5>R{O~+tOIRw>kqlJE^m^LY( zKY4-^&@TeIc!K$X`4J$TAR3vU#5AQ+b2?&g8yw|=loivi-Ow{rE`xyJ$N*eE!TiGf z3R`qTg#*k5B5~vcsn+kzMKO+@mOf$+z%rac<`3piF>Z5{^1lt(Fqc_anl{r*nJdgy zmLS_$%#tRD_p*Sl2$+C;EdgTzQ=3_uWmuNwSQ%@@S__yFu#n;gcG2mav_adWRjwFOH%r_)jFS{qIxm{)72~7P2O>sgQ2RCbKC5wimD* z((TxEG2IS3+$7!3fsT}00)cEE3rEa1v-xZRTgVo%#cT;%Dqv>;j}fqofL#SVR={oo zcHhjFvlS+;RI@c~t$;lQ4Do9*BN8hF>@8rQ|Kkhn92Qv^)55lkjA>=t1Uz2Ao+4wW zni%7CGsaNg7ZnY)?`6T(+RXN`)7cs9Om-G~D?3}jeggIvaDadV1so*cU;&40X6LZC zn>ZuDCqclW0-j*zjMDT?`G1@N&dA4ESaT06rl_*_vdaVmL zU2@XWd@T#d z7I3V9;{-fOz>@_G$szDH>HknxDBU|U2 z6lB^dA>@|(YS@G9t0IqHWM5(ru`jcS*;m*j0tOwKD&RB$rwcekz?lNhf=qArb#eBX zGQD9-3kf(|nmy)BZ}fjG0v1_>|9$pDkwItJ4+NYe;9OwPzew-4v^>Ycg+QCx&)F~7 zFWIlyui0L$0t_1zaxR3SbC_O*5wQW-|sYle1>7a5ByTxWZX+)|?Gz%h_@E9JmKH0){1i zih%0`TrXg)fEzY*j+_(c%#Gn(I9Cp=0-b;x1>7RwRsq8r*Dl~&{*N)h7|ROI`Emik z8P1RM7jTn+n?=q9nK+}r8E0g3eUqe21VSD#Yz%Ob9As1XbFjK}^mDMfbV>(S#SBqP z67a}<*)X&FVPSGSmqs{l;S#t+ZW1?{OX8Bb6b>|@LBQPto+jWP0UHI}E8so>Pv63& z69GgZm&IjsIUHPbDBu~8%AY0RnF5|A;9CVe8@>ls!{HU!w=Yf0t!X!=ceJ-kmqEHn zkEML0Y-1%H{f69sNEmS*Szz&XVV7BYY)ZfFg#$W4fnP$B6{;NTS8}Eg1bIi!^ z{BOD3+&nXe1^?qr0PZd`;)VZJx{eIiNED-z;(4Z zm})N1K#>?x99?8OykLr-a&Hq|8@XfLaqa|nl6yzM z4+$8kxJAI*1pLHMz7zKz_kq~;)7<;q838{m;70_!evtc+`-uBkz~BlE2zXHJdcbwa zM)eeS;|x8JW)69Ze_t^LHup>QaIRjuE;sn^YfCsxFf)VTg3$PNK6N$WH!`fI2e_1&B3VlTmIdH zQR7(7UJj>=0s=#$qGP-@38tei1tsOxQyTT=OS`3$Q*d6zOjqeLWjIxn+zU4-!bLB7 zBixMb!IRaceN9bzeY3v#goC4%lZ)F8jyDZBkKrkv9&jBCS8luU&Ts-F15U+5O}ISJ z(DM$Q&r(>y`6EAnC=rh>0N$324qdBJJjOG0?hgt@)5kX{Kw^r+LOERD&GKVGz{4Sx z1TLC5Q{c?$aVyjLBzFnlFr*QKaOGuU$0sP&gJIzlrK`XPRS|x?c>6cY zy8!#7)?&Yg+QA`3=zN)oCqoan%l7Cksfi=1m>Y_H9(sD*(JD5+KMwA_9wVYnOmZ8T zG?|z44g<+4(uLD-bP@ntfQpyx8b&10Lw@K`sd(aXI005p$eH8WIk|Z^I>j~mI8<)_ z&>1dhQCM{CUB!jP`M?{~Rc}yUT4thwWk z84hFssUhP@v(_3qB-LrwV&-3D3LKI$YciR=433d*;!evPWRBb!nX_z+NxN?s@ROk6 z1-wJRPi^8pMD;Q^nLCUJ9K(JwAiq<DMc4x} z({&m0GDEX&mO|I7(8NV470LPXZz@Z>blq?U+_YxO!r)3!!WJ~3<$7|NN)`!Qm*TU2 z88~cky{c3*W~iq0J)Vf(O13dqsh6okut!ITJ9e@(83ga;;zk{66c15|8+EW_2fNC! zm^?4w{o)z-p`+!p9J7tL?|*Bv%L>hSU-)OcWdFif7*0TwC{|*=SL@mno5y4ovdVJP zJqf0%>_+$yp+pqC2w*b(GW|OJ9(@+xQ1UbVJG`Of5<@T;Qgm1*oJnU&m?n7dNGsFM zOl3M512YZYKXNCtfLX{aX6|P0fwzyWVD4vDGn<&#SZjD|$P{@0#~{4Z<9&E{$5#-* z`i}h`-o~NfQn@^M_eM3>2=CjtlUo39*jUWn4QAysc+190ZWXtNdmP@cv4h*m?c#QG z&vJXYecTJ&LGC4Z$Hu4JC3t7XBzULM9kOMzLD>%3E3zZ9*JSU?-j{tK`&jmg>@(T# zR)iI8#ah8)Y&F)(%gWoz*UH~&f>pSc(kjAAZIxnGXw_)dWYuBSXEo32E~}MR>#QEK zdc>;VYKzrYtH-RKuzJ$!S*sVVj#<5D^@-K*R#&X8tzE3gTDx11v-Y%BSch7NSx>Z9 zSw~t&S;tt{SkJUxZN1I%`-MH*&MbxV)MGqn>KIRd}8yx%`Y|=Y<{=7Y;(nyu*J4^wobMRTYuX? z+hE&pTcvG;t=cxqw$Qf4)@VE3cBbuY+c~y#ZSS_d*LJz>O50VoYiu{#Zn52J`?&3P z+a0$1Z4cVMWP8~5i0x~(-`SqG{nPd@+pBiijh|pqkNnEIr%a9uMWt;-C>-Ar-Q=5$HC7b zz#+&X#9@L%xP#Im!Xeio-=WZ<*rC*++@aE;+M(8=&Oz&-b7*qVJIr!e>afw_S%(u2 z-#c14dO1#V%y-l|-r_jbvD0z7<7~$}9p^jV<+#joh2#B>s~y)nZgzasahv1gj@uod zcRc9$lH<#cuQ|Tqc+~N2#}kgH9KUz`(eW=Q>_j;+PS#GgPWDa?PO(n$PFYU*PK8dz zP8Cj7PBl(boZ6kboqC*lou)g@ahmHSINjki-)XVaDyQ{MJDuKh`o!r|r*lqUIQ`)C ztJ7~z7oGleW}W5Ej?T``F3w|}y`6oX{hb4ygPlX2Cp%|3=Q|fV7dw|a-{!o~`4Q)* zosT%5asJ-<;uza8-eY{n_>T!36Feq#OxPIZmMd#Aw(&5tO((TgY((5waWv9WgZ zx689GdtLUsM!43x*12k3b*{I#PIc{co$var>tWZoT#vb)aDB)1UDva&pSqrN{lfJt z*Kb^ZalPpJr|V_cD`Nx429FIL8#cCo>}zA+7<+W=+hb3UeSho+ZZ>ZIZY$mT-L|?t z=Jtf!lWtGB?RDGd_JZ3%x0l>rc01~J%A9dg6{v6W@?8j-w z#f?iCH)-6)aZilfJ#Npq=f)i$_xpIe@s;Dd#?OX3=H`vRbNr(5OU5r9fA9Fs<6j+r zYW(T(XU2at{_OZq$A3Hi=kdRe|84xm@qc=sws}tXoa=eF=L*mJJy&}^;JMy&z;lD=CeJONdp(bMzUldv z=P}Pyp6_|S@A-k}6|Zq#!Cnbolf06=QoPcwVh$Qy=8R`1t!o_^5rNeKbDlKAAq*KDj=XKFvNYK5ag?_?+=M=kuq}Ro^kb zp1#?>1-`R<@AF;hyUKTs?^@qM-%Y+-e7E}U^!?EHQ$HKOF@EuWNq#MUM!)HPGyP`! z&GDP-x7qJ$zukV%`aSQr-|v9m%YMiGPWzql`_S)Wzc2j0^83c`yx$N09{!R3x&CGT zmHyTKwf=4XGyG@y&-S0=Ki6OIzr%mN|4RQ={%ic#`9I|Ui2s29M*q$JPx~M6KjZ&H zfOSA{KvY0(Kvh6%KzqQ{fX)Czz_b8k!1RFm0Sg0`1l$v_EMP^zs(=Rq)&(30_$tsY zFe0!jaBkqkf$IYw4SXhWZ{YsGgMo(wUk!XC@Mz%4z|R7|3p^kAL*UOrY>-uuZIFGC zLy%L@xFFx4fS}-@2|?jO@j;0}lY^3j3WAD)N`lIQbV1EQEkSKTy+K0I9YOPh?h4u+ zbSUVJp!b5_5Bf0Zr;Zj|&bCjtGtl)&$1~PYTWq&I!&BE(|US zE(@*;?hEFF7YDBnULQOdyeat6;Kzb@1@8`iHu(AA{lN!u7aANI5*ivB78)0t7@8EC8k!NB z6*?tUA9_n@XJ~h5Pw3px1)&Q=7l+;*x*~K{=$g=Vp$~;_4t+9oU+AIG!=Xn)Ukg1J zdNTA>=;_ciq31(?3%xplRmLkPDKnMj$|=ewWw&y^a-njG@*d@K65$pxF2XCqJEAt?{)qh%UqxJqxEOIM;z}fnBqQaKj*(*`$41^6 zxjb@hx1mC#a*;8g;xnQJtkOS68WP)%9wf zx=B4(y-dO*EVy+yrE{e*gl`f2q+^&#~u>etk7s^3;0SD#dWto}BNj+zja5mg=4 z7}XUuBkIYf6KBhfpP0UjgvT@kw~_JP<3V;_kfh}{_bRP3(UJ+XUZ z_s1TLJrsL5_ClP0TtVC|aWmp>jhhq4$K4S(KklBm6>+QL9*A2PwW@Nal7K4 zk9#5RVBDd&!*OrLeGvCq+~;v$#(f?4W8BYizsCI@_eVUAca2xX`^E>v2gS$6C&W*V zPl->DFNm*=Z-{S-Z;788-xWVC-WY#t{JrrTy(MfEQRg!Je z(xkOX4<|Myc1a$a?2+u5JU{uqNP8}AU)q7R7t>x&dnN7dw9{#4)6S>;mi9;5 z<+Q8mINdtkF5MyBDcvP~Y`S-PczR5FTzX=9QhI87UV34ANqSj&WqNgbWBSze-gF^- zar)BqW$7!@SEWCaK9IgKeRKNO^vBX)N&i0ma)w_dl&ywIFLn)`MA(WDR6( z%-WK*BkSp`-C56OJ)gBd>y@nISs!J6oAqnf?^%Cl{gq8*%d%~O?VRNCeaC+ga!rKbx7S1c2U%0Svb>Z5=hYHsh z4is)I+)}u$@bSWvg})TJ6(trm6)h}!vS>%q{-T$P4i~*zbhPML(aEAyMIRJ>Tl9U= z4@Ex~{Zw?N*tS?+>{RSh>{dLk*sIv5SXHbpjwy~SPAHySoKl=#oLSseytH^{@w>%; zmH3q8l;o9Em(-W&N}5aBOFBvnCDTe~lq@J&RI;RGP08kxttF3_JXx}{dG3*3}roKePuJtZY`Tr#+ThuHoxq#ve(Og zDj!oGU*1r@u>Ah=wdD_$uP@(NzNLIy`Qzm~%U>*itNf$#Ps-1ge_8%b`T6o6%YUiB z6;uUVVO3#MVPD};;auTTkytUMVqV3jiZ?2Ls&uOis0^(PuT)h=SH@N*R8Fc)t1PXo zsI02gSN2xUsJyjuP9R+!>aVIR)z;N^)ehCp)vncU z)q&NC)j8F*)%Df7>gMX!>RYNitGla>)pu6kRlTTsN%cL|%d1ybudaTedR_I#>L;sT ztv*|Qp~kAlrzXCpxaPi^2Wr;WY^&K*^K#9Rn%8TN)*P!jS@UkqxtcF)zNtB1^JC2~ zHNVwdtfgz&TB};y+WOk5wVk!ywZ__0wV%~~Ui($;w^K@|G)!rnqMy<>W!ID!ryQE{ z%9PjY!t3Je66=!cQtP(W?Wx;WccAX2x+8V3*Bz~UyY5uohjm}n{ZMxqqIgt2TW?cu zU+-A&TtB`(q<&(3M153!Tzz7FQhiE&ZhcjKU427+Q+-?g)cUUa?)vHVbLtn=uc%*B zzpnn_`oa25^^ewXtKU<ZL6|A@X{ zzd^rQ|EPYO{&D?r{qHT_Ex9daEmK~49k z<@uHuT3&29)beJ_+bzdiPPTm5@^j0DmWwTyTCTLBR;rb4wQ99(mA5*!dbN7D`n3kO qE^b}j`atW0t&g-ZZT4;QHpe!9?$Ebbz)^_5T6#FXB%C literal 31996 zcmd_T2Ygh;*EfD=Zr_BkwDd|gf%I&$={?!>WYc@uY_b~&ge0WU%N?2^O;7{@l?0@T z6cs@Q6h##29UFpzfDOa~g33F0H=FE2^znK9`8@Cc^Y??B-Fs)w%$zxM%J-bRTiepu z(AFLpc!mH3BuIiHXo8VEupmlh<8-ZU4b4rZvgX=Ry1MqZGMT2eZe#<#TqtXAZW%~` zIcv5JAX$PXIARE4P1q2&gfHPo_!9v{AR#A$h+slNgb)ctB9TNWiDV*^$RqNJQlg$1 zL5w6Ch*897qLFAN+K35+Kp5cL10N6u!a)Rx1W_Ow#DG{32Qonx$ObA<4l2M1FcLI?QD7Vx4<>+#U=o-N zrhutn9(Wwg2MfRo@C;Z9)`JaTBX||;1h0Wz;9YP4yax_~Q{Xf>1I~iW;0y32xB_m0 zAHZ$!BX|G_2q1)3us@W-0ni3IKu0(fy2D{G0EWN_7z>p!4W`2)SPV;GDJ+9kuo`Ni z4%WkQa6Fs zxE=0*`{8@=Ap8&>hR5Lvcm|$@AHk2|Mff?q2Cu^#@N4)D{1N^He}=!nKi~tBB{@<` z+LA*_cTz@rkbYzs8BRu!kz^DZO~#O^WEz=HW{`zs5m`)@kQ%aB6mlvI zBBzlv$l2r^@-cD&`3(6i`5f6rt|d2+8_6x?OXLpnW%4z07kQXGLLMcLk;lms?sGzo${l? zsBkKlQc}rOI+abSsC*bq6;LHqDOE|;P&%rC8bghx##0lhY1DLT9`!gipISgYL3L4U zsddx~)Ouj*QvLt_ozeEQR*ahiaJM~r!G*RQkSU9)OXbP)J^IZ z^#k=g^#}EUCTKuYw1l>xrL-+=N88gwX?I#id(%F203AX{(us5ut)#Q)Y+6MZ(q*)U zuBAuOqv`SV1bQMpiJnZ)rx(x*=|%Kn`U!doy_{Y_uc15XE_yTlBE5xvnchwBqYuy@ z(#PnF^yl;?`ZE0m{Uv>czDnPuZ_z){x9MN#JM?|}H~M$RhOuSr7<KV;*Pb zGYgo7%pztn^8~Y=*}!aMHZhx-7nv>0OUzbg8?%#njoHH-WIkj*Wjg?p{zSAV*^<^8^i{)3O16BViVXzHkHj`OV|ol z!`8D+Y%@Eaoxo0IXRveGMeI`cX?7*MihZ74$8KadvD?^J**)w5_5^#9J;k18&#+h6 ztL#_oHTF7tgZ-Ml#olFqW$$qmXUX;BhH%!LGv~<-eFB6o}XfxFH9$o<6q%>BaM;rsJaegHp^AH)ylhw#?C4R6a2 z<=uH1ui!)YP(F+g=Og$yK8a7~vw0O?$d~dX`38OzKbmjk$M8*jGvC2a;%D$P`T6_; z{waPL|1|#`|2)5jU(avhU*-4k2l$WqPxw#y&-jb{=lmu9GXDktC4Ynen!m;Wz~AQ| zNCrrpB+e2SiL1m@GE5REQAk205t0~5f+SgzF3FInBsr1-Nr|LXqLt_*^^#Ueo1|UR zAsHu`BAF_gDVZyILb62ijAW%`jpPN%OOmaU*Ce|nZ%W>lyeByk=8UY6c1!0(4IyhaKT+-Y+x~)Z1r&Bi9b&Sz9wX3DFqy%}G zJUA)bFGZ28@KYoP1^PuO6O;Tx72!#W@Sv1nd3Yjjrc6mm3{Fmx`{Cwdvy@=Jge2T6 zNf8#PP$Wbs6p2dXOznuFgwIC8o^T)>2`9pta3Nd?H-QmYffIN^B3KBPLcfiKJ0T-H z2v1@dF`V!syag+vzpzi(FB})XL7*Q3R)Q~{cVeqfGrFa@p{czsp{~7QoTgo;RZH!a zx_V7VV|%i;p}o1apdDXrOKEN`%Fk-6)Hl-=)Q!}Q(P09HkNF)KsHg+rqk*PH?&X8*R?da zVqW$)vbCh4N!vWWO)a&}*VW-ZhDjRligV(z<4?&R_o;oZH$gdJ+X4E#lbz<|CN5QA<4yJ+TC2Haya{ zpt+;9PM3s9tEI#Ks$o|12;&lZCeuway{TQ-T8{-Qv7@0;t80CDJ_UG>Ce}7nHZ2fK_hOc={5fe zB3D~5I|EJ;1w9uzFktPD#+3MamK}z5o*Hc1)`j& zAS#I}qFS&M>;(tGQE+;Js39~&Em22k1!uuU@Du!n2yrw0%(l_6eYvf=aShEKZQXlo zxR@j!ZnboHAMO3y^jnvO1=GI`JD=_28g%2;Qr|wB8c7#wT1V)*<*}P`U(E}2jaayJ zS|eApn(Oq(22aEwOGf!K%u#I^(UiDaYGXEy^rre|Lt`V;#t_Y-1T+b*okWY^CNgD! zvbeB7Tu3oqNP4?&Oxr2F>T4&)cM%=LIAN$TT<|dxm`F?^26qvYh{=MxAnPKg64L|^ z!BZGkg~_CA@%}f|H|Sc`QYro{Qq0zjXliKh5Cz?>mvv?X_I7iR*Toa!e+H?TP0XoO z6(}3925N57v`*|IW)mgGnam~To6Teau~6_5yoF)8?(vV$HKDSUc(PhmkloR)scqCH zw6P!qdY~t-X(6IaW!uedkCL3Yea2kFxqbs#|fWp z(*DHT#D3x(;$7kZ@g8xIc%S%yI7EC%943wsM~P!Xln^7t2?;`ykSwGM=|ZNEE#wG! zLV-{ul!)C=5GS!9o+i!^XNhyfdEx@`5%Dqc3GpfM8F5i46KaKeVWiL~vY zhA>BXTv#M56`nR%tzYWZXtY|Y`3Gv$gzEu%Euw4dQK{lV_ir2DP~UE<(XZ==ja5qv z|G}_E?Oljvw=F>b`shgC=|_rJORN9ENPR63Tlq$8;j(p)j(J-@CU%pw|KTxB=8-T$ z*YxPfcl0AG)zX@OZ{$Zu{Y^h=idx$A4@NcarpX$6gb3SeQDG-FH?_AmH#TC2;$evb zKtG4Hf41_z=8(|RqQr`F1okK&9hK3KnxU3Xo!~b?bR7J&4Q<#!>&DbJPQ*?LR;qQQ z)%Bt`8P}-kXsR1oplcJMpL|_?Ojx}(Fg!3s8;V~&^)2;oXPTyMWQ;-)9uX0!2nh)f z4v7d34hjpCn>6X|T^kr&Ums|4w19OO z4Ej_jV2FO?T(wm74+PL;WdD|CZCi`3&XlkA`Z4m=(u{vFhLNwi&3e^fO5a6KzfdjJ z{R8?YYv_x6$>XpW^ytRP^g|c_t3!+Ws*j<)^h1}brFH*c)kdzGuD)-5p|`@o7szpt z1^j?N2mpaXxlkcg3RUYs5C{ee5F%6yYN1BZh%TsYZfnCB?B5yfeWB4)!ZGkew~8Cu z8n7FeG*Z*5!On7PzNTq}t}3lTt4nBXOmA!J&|!Dk8r{%XqD7k4s^xNG>c?KDAhU z6WBv32Nd>6sR*R&DUHBXdMV9_-laCqp%Q5N>{$!ya8I4kAdJF2N9*U1`T0)m<~jN~ z$Q2<|ODD^NB1~s78nlSC8o?OQ1e%30LX*%ew5$VTK`W-!E{qjgF|D@$)osac82-aB z$I8j_um}a-nTU{(sb!Nxg2IDL7cvdZ>~kTrz-+vb$Ak`H9A3zHJyWt9G9o8;l~0xj zV_t;fjV_(62$GvpTL_l+N$pASlzww23X^&^C%d-ngX_DyMMd5#DyzVnK52A)Be6Qc8AVn{UO<-%EB({O=n8eG%bV0x*kYQ1yu77a{P1$}9e9|YaPr+xH*5|@}VF9MK&_F94 zXst#YBs(}rFWF(Hw621$`=s>^_!iUpURW$VfoUx<(5f3Vdd>Or$)R{Qm}QEo6(Z~O zYCztz(4WAseGwg7Aln(WFj~?q=#Nmkitk0l920*9^|0}D4?aV zTv&nWJ!7Ef^PP0`WKm-A3`4^r@Nz=}gH4tT2g1QPl!t?aRh@8%@T^(H0S$I^wOSfv zbeS5PM_^YeNf817YYPtP#S`;t=?GIGk7my`VRt0x{4Y`eRf;H=#w- zq%CaKG_}>WHng;tVbo4HAy?BrQdlbxoUmHxJPiY(oUnjFFc>N@KA|c|H@3;rHH~N= ziOHB;E7ml2=%heO2wnR45Qf4q3}N;3>4M=ziRlGHt4J87mRe&d%>-dHu4XNahB0E0 z`X~4Mj!unyi-QRw-{OTAI$@%)!F*#<^`>~eT8d$k|0JRoAcCX*je1BeThoA}mWRsosO8f;t#7-Rsu z*BCMzhYc?Vd)(6#d(p;%_STNN_KsGaxpyFPGcifiG)~iIe#0O-<)Y|R2rmiY<)cSN z_|>NSY1;~nELB5n06Srgu&oo;3fuKl6rtkGrsnZYIUVhd4NdydN*c87Bi-X$F6rSP zWA72LiSStuN5Td;3XX=2aE$P>@QU!Nuv2(V*tH%u!xlIew!$``5Oxc%3vUQ}guVDA z`j(eBH;+ldenxX^MH2R`bgj7}B#vP=5hu}U3!7WAMBuZVOG?ZgnE|9sR~9z+Owh3C z+~&3h5y#5bv|s|_&4flw5kup;-eE-C4C9d))77+gyE^W1xAdzau%;LFa*)D5WU7H@ z(?y;M!kd_9<4Vi@8YlRT9EaU$z5fMg!Py2_#69kWfq?POJcyCAPWZU+RwrB_yp6Ft zd<;|~7T@05&@{pv;qmMC`;48Jz?H<{jc_S^5>f&M{iX{>f!yH>wPeh=M`43AI- zM??gL_@$&MQ~VS`DGEOvR^r@FU~*7+N?=lGuso@FLU^b;R8icJE7C4A{0Z|7GV=Fj z__`>pufSK~PWT$!1$PT4gj2#9;hb1t_e4Uug$g0 z0lk(v`EQ15@Q{9t)Bg+$FbyUi2DNY?`bZQ7kLgD}`@axH!PEMo&;MJoDZHSk|Iz<2 zN(evG5Btf#%2BhB*r1*+!7nj<4==+ngwKSFUGNILDtsDt7ZeIz*+~d(* z)0QMblIAT*8n?VIww$ritR+uc_Pvzuxsn6O!RDllYc)2oBb^AJwWK}iKspNF3f~Fe zuO*#H7t&R@iGZbWPc(ReSV@~FKf4p9*rpV8j1l8!gZ?hijS%y2SY_Hi(j})wG(q^5 z=-HT4D{N?Q)amUC=}C-#fgDB-C%s5-(nq)@+!5{z4-g=G@<60N86?g)fD9z%!Vki2 z;m5UPFsUFzgr9_;g+b0U-(Vk97S@n@X0Fl@F7G&15yH7Iq^*APl?ub}!)+Sw~oq zT2dz_YqgqoP0j$QsWsNX0Z39b6BYgUYTsUBx&Bgn2S=HQk6aPfUH8CCEG+w3;bdz! z9}SsUoP|qh$Id}*2hRB8Y6nY!EGy`!tJCSUI_>EJ10{p3?fR&a=o&mkpaiZyM}xBrjLF7B>n+`cn&3^!+=+& zpG$#Qp^+F!NJ&A0$pr-)C)pL`jX#HknkOPd#Ean(*wZlKjMl)ju1N1buj5(;RRI=3 zT*J^^hj=n3wy?Fixm^Ib0&xJY-Eha%he5b5L98^)$BFG)oUR>BJmj5w0d& zjT4M(h_$$;a0AZYZO65Q`*B+9B+gA;#`T0>5!V3#46Yiq$F+ho48AFFePBAS3{-(! zPz0(#4bWkrrvq06E(S|+{om_g57=+uG6aUdL|pgZ?mysN1fV`>B1e!Tt9mn}Sp3%F zOASN`=CcxiG9Hc5WGnVzuyPnfHj#3&g&ZsVfB=O6E&PZ8g8;i8D~oorgB*un+l8MH z;1J*uu+YEZMC~#3ua9}*#1`zK{TGe!oN%LIe@#hjRM0+A^gaKJmLe>vZ+VKGj!&UL zB2nhWw62(8&AYJG&k6yFfm1WdSq7%)y2zPgC@C#$)@mlYYT8}HA{BDi-0T5xltJ6h z6%*}Z6%no>5_}BT782t(6CaX`$tTDqOgr=cyfp`*)J?8 z0RwA+DN4Txd0?ntU`j-gG6mlZmdpQ=KyXlEVpwo+qF-1jF7w0HeaU_aDY*16I6PF2 zJ1fKR3obJji7nQWxA@@8#+KWZF_Yk)XbEuCTeeu~yTXj?o!? zipAhQcHh&~VnD*=mi1(Pk|S`cuPaV4go_D}z_6(XSb{uDtnL!`%CI{^xX~G2&_Qh3+Moo zH7z5Ry4sErBSc`#Y`@GT2G>P4jA$~WTPZ5k-oD0J8>Y}8Cbp~-a9$fHv5nP@ZCRR$ z%^et!8uBM<*>Hq@r&z*g6Zr@EfFdYBL5id(il(q34n{zMKnMb%2!tUJjz9zgkqAU> zqBx4jT)#=)r20`-RDba#MI(?WGCfWIuML5D2s|#Hrt(JpJPKQN*oumwg@L&u$f7R5 z)79c4M3Lv>CKzsEJg3<3e1_q3K}YQv+`8PPqjV7N(OodA=Zb;RuHBb-NUN?5 zhdjn|xdBEdnr@jmw(+`1=?vvaIZ@7p1?57hC^u>-cG^T|%)nA{DJpULQX8C8ZRlt- zOiVm%x(V%uJGL!`wB;kW5Xcq?1Y!`#Jx9qX4?Kn^HH;dL$8n*2U=ZaCgG(`9)u?UN zH5KE?2G6~sP9)vbZg6Z|wcRCR23Jw6Tr*!~1&*DJD;CGfMgY48v1ciNDgX}`NXe-n zDwtAGA>>UFRO}{a#LcREwSsyS$uyOBY4EF0G^qhKQ-`;x&q$3cIKo$aVSQOOK z0DaAuKi)6Hsld|}D+!g&B2E9ElZE|b12U|4a;OMm^;#;DilVSwB_N;P%)r!v`hFJn9rn1D~e~sUkv!Kn4Pt0`bqB zg}?2i88}l$mG_;!=%Ok_hWu&S9aTkD>tp)~lU_`qO7 z1+jusiSnHz;8HwXkx$iQ%$vf-K1K*PtY{Q9+TgkOh?$w5H9yW>RHHa8(b4}q%?%?o zQO#nCX_&di@ls+eKa`vu)fOGF;9@-u3^KJGaf?s3<~#(TK77oVnSdsyUPVBQaA^l# zdp(96aeO)I`k^O&>^s|Us`cNX-ZW@^1jZmRvPVf9w%~11bT+tTm(Mc%UH=ST8h7XD#9d|r3wwvMTTJopNT?r5rI}A z97~(t4K;Y7fkD^{RfLC5HRju?FQ{uc;Yoc-U7@a0Um?(r06t;k5E#FXx=!7|S{*;~ zG68{Udd2>j;9HudtJjyoW6F4jJ>El)_fc**lA>QzmM`MdqQ_?3(A(4|rp*{)e0O@}P%_^Ti?E+)gnPzz#p2FZRvanj3Xk z1>m%*xJAZ6d}%+k0&zN!#^AN#DF_-HnE8UQfh(cn(!yx$1usBgaqrTi=vcE^#?kQz zEJR=to+XwOgPw7Z7i`UDnM|jd^-8C)y?+9MC8DnFkNcT=qweuF@n*eq=)B%N$w%Nx z<0Om3Nfy&si9dzF)4h`{r>jhdBNotV0moCz#Dv8}J!xFZu8#-kI=cR$rX$6s%f+Tm zYs{w6NRP!rO^>0Q=w`YFfoBj{iNGoZR%cv*k_U2!8^dz?Y>i1&m^ z{yp9wcDw$hiJl`pB?dZePiN!v0!GErbHm?I^JiSy6dD(Wt*58b)9C56KqDFp;ByE( zkH8uPIuYnXVC{N(7CoDu0~GXJG5A@Bz>5fM5s&6}G3k#Z6LC-Vbt*co=*G5*!GH)D zbVtVc`7#`Gi92X4hcN^`B7|Ug_RMGm46=wVXmXQy&haC3VnEn4d9y(hb=aNkmR{V$ zKvMKi3zD)$8`jbGFg4?%m(ow+d_Mgo0xxvZ%Me&^6flD-Nzl*V*!UTGHGcMkUP{M~^4T_HueJ1gvDb4H7U9j<6~=GHUidBUg-e15_bTF` z5L_@85+2^8hv}E-ZN2l`j=)R8FeBYp=$)dJW0Bg>Nxz1`Rxyul5YpG_H}NfTz~oMP z4+7hIZ@oohNT`!az_zMWKaJj7@6qq~j`aZoJ9@`DOyjyWljlU}X*u9=UPhTK!67KXTqOiPHoQG`qs43- z4nswEK+ks^IpSM-iPo1piQ$^w7s0yOMwyt}BL(`HvZ-AkEbCKtqOQ(qYMh9lo@~OB zkl5HMUAixy8mTQjLtOXc`_nr56X9b51QO=IIkU@QrD#)|1rwlf2mfjG;eV1|eq z1Xs2oa2$aXdY9rP0;jN);OnPF4vV6a+}hgQ`tU(E#G&G58ih!Qb4ggH^w=bpmjQZy zij{L%BXt)!>phfiufQNnq9-AWiQd*HPBb71Vpp8uYSgsghiCD?B8+5qO>EYEt-B+Z zJ29ytA^=8(_UMcUn$k^eZSH8nL>^TG!QG%B<4*sKRq)&T9cOTYc};h!gYh!G;cNOK z!0@44keMJR1nVFsn8D`|pVV_*BHKmw>ZMmdck$F@;U|}MTEn5i2xw`3&ziNSQ1K<1im1 z@QJ8_Mf|Skkc)^DE=-FzHLgrPQ)Je?n88;4GXyRgO0o=og`wx-OJ+SQ8MRr@8gbxD zCIk0?hGKW)B6ZA2k%RRN4x7F};L9!o1LW8j)qA5ZJ$y3JCZcC)sA$8x>(JAp+Yp-E zH4f3tOu`s1)545pTA4Pco#|l4G2@vD4EBbvB7nW{YY1FN0IQ;}5y1ZUw+LW0^!;XL zGComLnQ6>)Mqm&#!+`PL#ODcP08oKoID#DrPCyVBQR`j4he2E;UfRQRa}fCd;~1}z z!AqD`7|UgrGEXv3G0T{zndQt1<{1WC&|3)LEbDCqenbFk)1MK*LC75h?ry@Ieb#{G zGM!8pvzA#Ws;OVamo)Jo9EhMBfwoLJae9Up27O$0fGdA6oQ=i4>Tj#UtHOMZg>Gd zBiYd8Cj!$(MqFfYb=9Nb0&|7AicQru1Ob8&pCd^2fD4CHA1%{20T!6=nC~eCa|_2? zupfdrR?I?>#%un+M1Pr|FciW3%>2UKL6Aj|N6?}NieS#`;RSK6SU@q@Yx>M_&vRo2 zq?mbNXe%+cm5Poley+?lTi349ie(9ghAd@hXlZC@>g%4yH5C|_WqCa=3-P(oT#x78`jYPYJA1ovkrPtV?2Vm@8ET;6YEU2 zv#tmZLC{|GK%gVe&Gcdxe+FxGOAYJ6dSlwGCp(NC&Uzteji3#Jwg}q&zl2~IXB)zX z;giaSBIxipPyjZX6)ij)gP>C<8;9_74dMyv`^yj5BphV3N;Vlm7X)2<3_hF2ni+gk zki$5wT(-c}G}9)KhOtR0TV@uCu$62zo}2z_8CW%f?%mD@TPseZj@2S4L(sE#8Y9?I zW@E&$jUpfcJ;VrJSYhfauq|wxS=)5BLxdsVFtKf=pl{og3u7k|Dt0o3ErA@P?$GPe z3>G_4%wXXI8!R@Ei)kn5ZK5aGnd~g1o(M$Hr$KP@ zzWdldbiR#;dAZ>*2mH;$Y?fbO*O=rNV328kfqg+dij(ou#iQ7#+A+kZ>}GaLuROhk zV2E+kwu_s#gMAr6ESh1xo3@kPZMqRA0F6;D_Ofq3)WV3%7+bu@ekh*MgY5h42kapP zBM^*4Fbcuwb?jmG2z!)0h9DO45(MiI)QTehzX->$XW372gw38~&$AcUkJyjdPY{en z5TCwy1QQTUL@;SR`x$#tbmiI0>=y_s5zN)cOfVnehf?qY`h;Wtvq*}e{Nt~&n@0lh zhXEkt9(}`p*8@SY-y@jZ13|Dqus>l3oW0Hdh+qnWsa@>P>@Nsn4=nx9!58*E`#_A~ zpJN^v;1`HZT{8aMi^1q&nC|g8n!}Hob#V+vMqmcM)5Y=P+f02UG1J@oT|KTQ7!PN~ z4Z!{A=Qt^DiC~uac98yUw)y0Y1KDu)k92UO`Hpdzn4lR<)*)rV}=}+bl3bF zDGukndsxT$Aeh&~I?kU9FzC#_qRd{fi3{dJdP(2|SlCM}|~ZPA(cjoG3F6 z9LFW#Tg(FlC7m3W%HrNz$y};<>pb?n9s--VOfDabH zQ@Lpf>hvn69>Ea^;@LJJI10hh2;w=8L9ht}IUK?ZnaRx}+qpU1W1<@39v641SzK5P zf@Ae=R4amQ2Bp+4ZrT5zfgEmy2}HxK>IHJR=S**OntoVk2IO!XxXq%1+Q@A}a2$f; z|C2xtw}X2{Jmh*ek9!rtiALevg@GJyH}^XC27;3i#3p`9k8S4ma%Ps-6v#13+I!pw zrpB2u0c(s+j&di=nwX$6#wKUE3*y?(aaf;V0iA9J!Tc4#f}yM)_@!@v#yG_198P;~ z;4X2Oxi7dcxhvdN?kfZlf-?}DiQp^*XCpWV!N)dm*SQL`YKm^sQ%Dw7tD6PkJ?28+$lVJL4;^2rkoK>JpjK{m8LdKG5M$Qi%9*Ze!Mp_uzf8eday+Vf=93i$23+m*Qyz zmm|0WL7d6lh2YBdJbp-m55WJ+`5**Wi97ME`0_l0YsA6-#QprAPWC;TaO{>(K9Y~_ z@pyQw_g43KJbXNl-5QgW7q8?~dfTQV_*`$>3_jE7U`czkdAOz`um^nLbNIa8?)eCI z_I5Agi_M2B<7-6bm-7{TC11r?^Ej|wi{Ls0UqEm@f*TOrh@B&`ECMrMN8Q6r*H=bh z-ft4$Vcxr9?SVJ62hmMzZZ~8i^m!&MT{uM388fv#Up|PTYB6(R+EJgNNSvteA(m&E z-ZQxU57Qm`P%D$%Z|~rP>x`L|-U^^UOM@7C$ zxZ_0HU3{B^OE7j>h%&YiMPZ@ z;w!;VOCoq0!LtaSLlAqd7ZCiY2eOk`;wri%{ZcVjkAeC>Gx-Jxo^vyxb~$>PPU^<; zIH}=k*5A3x7zV_^hB#n11xbqGDo&M%SG!AB^q9UR(}3yY#H}9F{};db&CJE=c@|HC zhsDq0!B6$lCMm?yCMiPja}i%O$(M%*VpAIug7f9wDq2z|!JzOu3^BV%DkZoWc7|9P z2QMS|#X5;vQbV>&u&{lJ;B|e7ioXHk?<4(^5t2qsTQXA8AQ>gW0r3?C@p;5y!nOYg zk$%Z|$wYkICD=6H_!~&SWST@U+6D;@d%o$m4U$>d!b)aKaOi^-$M-#EK{8LWz|<_z zLnMntZo}_HyE!e;)Wk}bN|u?mb&)LBZ_7=+Iey!$?JCK$J@dc-+z-Zibc*xnl3-`( zHiAF(&SSk~lNs$e$%}ea|3{H_LyZ~jZIYMG+NMih)uZ}9i)|~-=doLYQ<|a|*aP!R z_7Ez`J`D4dq=@3*eH7-G>=9vp$pJmgPm+3=|5sC`b5Qbrx6&aYg7p;|hh7XNs| z75t+OxAD(4NU#;Ol1Q2=D9h=Vb1mmvF0@>1xyEv{<*Sx&TfSp? z!1AEw2mNII{Q5=qi|d!rFR5Qzzl?ra{Z##m`c?KD+wZY{PxRZ~Z&$zb{l4q>OTYV8 zoE2{+v9h$Xvx>Bewu-fiw@S29TBTT}S!GydS*fgYt@5o3t%|KmttMJcwwh`+-3nRF zw3==8nAJS1`Bn?97F#W`deUl{)pDz6tkzp?wAyU7rN6YlQ-7EKZvEZ+PwM|z|9SoA z_g~om`~LU)|K9%r{?f9M(hli(=|t&d=|$-`((j}>u*(kc-x|^&smgYo)cyI>)-qy573kdaQMub%*tMYr%Sk^(^Z-)^n{Nw|>%k zwe?!-?bfebziGYK`Yr4I)*o6Qu|8&f!upi;8SBrizqbC-`e*Aq*1uZcx1nqp8_q^z zV`*b$V`JlL<7E?S6K9iPlVp=@lWLP|lW$XKQ*2XeQ*P5?v)X2}%_*BtY_8kfws~O7 z*-C6JZLMsjwsy7-wobM#wr;lWw!XGuw(+*vw#Bxkw&k{!w$-*HY#VGx+m5kqwjFCb z$#$0Q65Exwt8JgNU1Qs2`=aejw%crX*uG-B({`Wj`?hCnKePSZ_Ok7lwpVSxx4mV1 z+x92hUu^H%0lR*7Hg+;QKf3@sxm~bbh+V8*yj`N5(k{g=%`VTb+HSPn1UqCm({8ri zV|MfGmfAgK_q5##yOnmU?Ow3kYPZYofZb8M<8~+QPTQTeyJ&aG?hCssc3;_DxBJ2F zo;_(VwYRf(uy?X|v3Ilgw)eI7w-2-rvRBy0*r(YS+H34b**DrZ*|*rY+E2EhYCqi` z+0V3}ZNJEVh5b7F9rkb7@3G%!|F-=*_J{3{+8?(+X@A=Oto=p%8}_&DA2>h<%7Jy@ z9V{Gd9q<=9F930cR1;A z+ToJJPmZi3?`YxJ&(Yd(sN*olV8>|3BF9R{4#)Y9D;!rjKI^!~vCDCt;||AH9CteI za&mVHbc%3_a*A<^b4qZ^aLRI0IpsR#I~6*$IL&g}?DVeF5vSu$C!J0^U3B`!>3gSJ zPCq*R>~zO@kh7z+mvg9dxO1d)v~#R;ymO*+j&q)Kfpd{_iF28Ag>#kjNauFvMb0~& zk2`fpJA5iZd#u`UTNNiNAQ1uhLP<6ItdnddU! zWuePrmnAMwx-4^9?y}Kkv&$BjtuEVLUUqra+`M^-I^QuGd^|xPIgMo$F24-(3H2Bix`H<;J*iZW1>eH#;{6Hz&6y zx5;i(-KM)Cw<~Txxc%t%v)i4a>Yy893Af5=D~En{VtGAo%>Hc)0ObCC^~g~%dh z(Xv=sk}O%4DodB;%hWQhtX?)!Hb&Mg8!Ky*O_9x$Es{MUTPj;Fdq%cO_N;8PY@2L{ z>=oH=*&DJwvVF3{vQx4%vU9Qvvd?9gWmjZh$*y}ic!YZ7c$9k7dFVVwcr3Q1otmk>pi=LM} zzx4dd^Sb9v&%472FP+y&ud!a!z2!8;muOnW^ zy-sHrgw+;H19dyi@le6uk!Bl-r)U)_g?RV-iN)9dLQ>b>HV?yP46GP zfAYTLeb4)M?*~56hw@>4cpnQNTOWHLM;{lTIX+MNEc03Jv(neX*VfnG*U{I-cZTm` z-zC0J`abRZyPw3*($C6ofZs&FIev5f9`{@5_p#qKzq@|-{r>O={**uKFY)i^FZFlx zm-!F#_xAVm5AYB2SNMnehx@1ckM`f<|6PD%Kx{yHKu5r$faL+J1D+4)3RoAgBj8}b zp@1U+#{*6UoDH}T@JYbMfXe|_0)7qnE#Qwp5J&~Gfs(*}fzrT%fkOgq0^I{c1C@d8 zfsX|~8+at}qrh+FwA@MVEsv4M%ai0O@^pEYJV%}{FOrwaN6VY!W94n~aq@}sDe~#^ z8S+{3Ir1g)&GOyygPSByCvq5)* zsbD6U54H^MA1n(F3r-0x3+@P>5Ii|}S}+Qp75rN8Tfql|4+S3yJ|28B_+s#l;G4m> zgMSXbtB@+}6yb^(MWv!a(Wq!vv?>-To>8n;Jg?|dY*oCe*r(X9csIm5Bse5JL=~b9 z856Q10xfk+VC>CpROT$n|eRoH;A!C}^64q?N?0>XmALc+qs;=&TclEc!%GQ!4%Eecy7wk_=C zu$^JM!VZL;4m%h2QP`(ppND-Bb~WsJ*qyL@VZVnH;bb@y&WBruTZKD>4+~EWFAi@F ze0UQ^cK!dlA1y4vut-^p5n442%qp42_J7OpHv9OpDBn%#JLMY>J#1IWzK! z$Y&x~M?N3f75PHs*2wLVuSC8UxjXWW$P1A_N7+WnqavfCqGF;lqOzlMqY9#mqe`P1 zqdKA{MNN$oqGm)bj(RHU>8KS^&ql3@S{wC3)Yhn7Q3s+9MIDYh8g(k_Y}AFQkE5i1|Onv716$mp2pxah>_)#%rvKZrgVeKGoS^p)sq(O*Y@8~t4q_ zvAMDNu??{kVjqv)8v9x7Z*hE_WnBNbfpJ6PY~sA)LgS+1V&f9xQsUC%vf@;6<#Fn` z#<;O@?Q!Gdro>H;n-MoFZg$-2xJ_|e;+W! z@Pk`paA9{_{J8iD@ss1H#!ru58UJehvG^PDcN1(A>=TA1_$SB{6bWGou?YzYNeL+l zX$dt6PbKV2ct7F8grf;3623~fneba8naC&FCI%!%Cl(|YCzd5vCaM!_6LpCr6GtaD zC5}yOPn@5)F!71RrHRWDS0t`Vd@ivwac$xYi5n9)C%%_>CGl>OG|43?I4L!$B58cm zf~2)cTasQ%+Me`!(i=&8lHN-?m~<%VRMP3Bb4i~kT}t{g=~mLuNq3X(D+wi3Qc6bY ztc+J?D|3|v%3@`ivO=js26O)z6DamQcqmt() zFH7E>{8IAv{wevFC`DZ^7rQ%0wtlS8+O)B06VfK9O-n;*bJOOhElOLG_GH@XwCB^h($=NzNP9c&-L!*ghtiIu9Zx%z zb~f!w+O@Q=)4of)mG)!WFKNG~-B0hI?wIb8J}liU-6!2IJv2QcJvu!$Js~|QJuAH^ zy*j-ueO&s)^eO4n(`Tf=n!Y#vK>GXXAEqBoKc4<+`se9iq+dDtjMg+)MRQiM`X5Swq|x@PRN{;IVE#t=B~_-Gk?q?vdAnZ zi_fymvdS8o6_6E_6_OR66_pi}m6uhXrOv9&(q)avYR{UOH92c)){Ly#S#z@<&sv_f zI_tTtHCZoYZOnQx>!qwWvfj+vleI7FaMrP`6IrLT&ShQ5x}5b@){U%hv%b%|pG{=L zY$}`2w#@FIJs{gYdswz_wtseDc1U)3c2ssuc1m_hc6oMXwmQ2udvf;FY$1DQ_MGfh z+0SKnX0OZMki9wkmFzdN_h!GH{ciSq*{8D4W?#tuB>Q^yH`(83|B(HM3aBU*s~V(o zRk^D?Rl`*YDy1q#m9ENE6{<>9<*G_mt7^JxhHAEIu4=w&q3UVXD%EqUPSsk~cGXVR zF4gO*eX6%r@2cKYol>1weWdzCbxHMw>ZL=CjIYbVb!{qQe19OJt*ycFoIOn+L zB<0lRjLUgCXKl{*oL6#Q%XvL#PtIF8@8lfMIhAuZ=X}mbIiKcyo^v_pZtk$$l-yCd z6LaV1uE<@L`&@2k?z-Idxv%8z&V4g?U+%lP2XhbQ9?m_V`)Tft+*`Rn=KhlVYaWqD z<}rDEo<*K*o>QJ{o_pT#JfA%OyuiGqyxhE^ywbdiyqdhay!yP6dF^>9Z%*F4yajnn z@}A0Dp7%`N`n(tOw&v}~doAzvyghmQ@($*m&O4X)QQoI{pXXi9`#$ex-mSdb`Fy^0 zzFod!zDxeld|AFcUy&b{ADJJMAD5q%pOc@TUzA^(U!FfAe^maM{FeN-{Eqw?`HSZN*Q8=owv9PIdY++mBqQaL7_ZNOtc)jqqB59GVD88tusIjP{ zXk5|6q8UXqi)I%sDq38$v}je)>Z0e1HWqCv+EVm-(Y~VnMF)xw6&)@*T6DbVS}|X2 zU2IqESnN_fv{+W`SF9)wD~>FVDUK`7D$Xk|C@v~4FRm)CDXuMUE^aR#S3IG3YOzo} zvv_v#(&FXC&lImJUQ@ibczyB4;+@5B6z?s5yZF80_lpk|A1=O8Vo_pSGOWbA#IGc< zB)BBBB%&m`B(p?Sl2=k#Qe0A2Qc+S>qApoevaRHFDJ+$h#+O!`MwD&1cCO6kth-KB4q?knA2dZ6_E(nF<3N{^LZE4^37l!caMm6esv zEn8LgYT5p>56TXg9V={*EGn!j22>2Lu&!{gkX3k8469I7gjGaV#8kvr zBv#~98TVtNItSX8mN;)#l-70*{}sn}NWa>dSy-4$P~}=Rw92DuSXE$EOjTl4a#dPYc2!PQ zUR6QW=&FTPE32Nb>Z*F7YID_=s;yPqtBzIOs`|Z}sD{;aHCHXE9#m~#?Nser?OyFs z9aJ4w9Z?-s9bcVPol>1vT~u9OU0GdST~}RS-B3NcdP4Qo>gm;}dQSDc>IKz{s#jHS zt=>`nYW1$_H>&qmzg_)q^}*^x)t^>htiD|RW%XCpH>$s_zFB>{`seC9YKhuiEmxWA7uCDfZ>smH_p1-6530Xc-&g-p18S%mwuY~8Fuu25GD{b{a>GN>hR#gczY2 zr5U4X(X?sCX(ni9YvyX^YZhrXXkOLq(!8PBtNBoKRC7XeT60PBrRFQm4b3l_Up2pJ z9@JXa_OBgSJEYdWc37=#RFa_gUT7 zb>G$9s{66-m%6)JORb&OQR}RA)5^4-+5oLW8>WraMr+fxDs8SdUt6Lr*H&rO+L780 z?Ii6K?KJI7?Huhq?R@Q1+D`2{?RxDd?H27;?Jn&e?OWP+v$6f*M6bB zs=cPYrTtw8b(D_LS?H{E19XFQjyf-$x6ViBr;F7k=#q3Px^!KwPOBTC8-;((bcSxW zZmw>=Zjo+@Zl!L6ZnN$s-FDq8y4Q5C>)zCTpgXKPraP&-sJpDYqPwR1Nq0wgPxpJh zq`qIhw0=;%YrT8DXT4W_XnjO|bbVaCvOcfAu)d_etiH9rqkeq-r1~lKv+L*9&#zxt kzrKE3{mb<`>vz>3sy|kLMi2NC5E}kkkcPj;*ZOn+2VH`_y8r+H diff --git a/Example/KeyboardSpy/KeyboardSpyView.swift b/Example/KeyboardSpy/KeyboardSpyView.swift index 55e8f1b..d1b6509 100644 --- a/Example/KeyboardSpy/KeyboardSpyView.swift +++ b/Example/KeyboardSpy/KeyboardSpyView.swift @@ -9,14 +9,12 @@ import UIKit import KeyboardSpy -import SnapKit import Material +import SnapKit -class KeyboardSpyView: UIView, KeyboardSpyAgent { - - internal var keyboardEventsToSpyOn: [KeyboardSpyEvent] = [.willShow, .willHide] +class KeyboardSpyView: UIView { - private var card: Card! + fileprivate var card: Card! init() { super.init(frame: .zero) @@ -54,8 +52,15 @@ class KeyboardSpyView: UIView, KeyboardSpyAgent { required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } +} + +extension KeyboardSpyView: KeyboardSpyAgent { + + internal var keyboardEventsToSpyOn: [KeyboardSpyEvent] { + return [.willShow, .willHide] + } - func keyboardSpyEventProcessed(event: KeyboardSpyEvent, keyboardInfo: KeyboardSpyInfo) { + internal func keyboardSpyEventProcessed(event: KeyboardSpyEvent, keyboardInfo: KeyboardSpyInfo) { if event == .willShow { UIView.animate(withDuration: keyboardInfo.animationDuration, animations: { diff --git a/Example/Podfile b/Example/Podfile index 5605990..b092a9e 100644 --- a/Example/Podfile +++ b/Example/Podfile @@ -3,5 +3,15 @@ use_frameworks! target 'KeyboardSpy_Example' do pod 'KeyboardSpy', :path => '../' pod 'SnapKit' - pod 'Material', '~> 2.0' + pod 'Material' +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + if target.name == 'Material' + target.build_configurations.each do |config| + config.build_settings['SWIFT_VERSION'] = '3.2' + end + end + end end diff --git a/Example/Podfile.lock b/Example/Podfile.lock index beabd7f..d11bcbb 100644 --- a/Example/Podfile.lock +++ b/Example/Podfile.lock @@ -1,13 +1,13 @@ PODS: - - KeyboardSpy (0.1.0) - - Material (2.4.11): - - Material/Core (= 2.4.11) - - Material/Core (2.4.11) - - SnapKit (3.1.2) + - KeyboardSpy (1.0) + - Material (2.10.2): + - Material/Core (= 2.10.2) + - Material/Core (2.10.2) + - SnapKit (4.0.0) DEPENDENCIES: - KeyboardSpy (from `../`) - - Material (~> 2.0) + - Material - SnapKit EXTERNAL SOURCES: @@ -15,10 +15,10 @@ EXTERNAL SOURCES: :path: ../ SPEC CHECKSUMS: - KeyboardSpy: 6162f98e3047f1350ac2b75036fa8025c5faa815 - Material: 09b50565d8f824bd74881eba12d7c549b41f510d - SnapKit: 12b24f569cb7c143acc9c22b9d91b23e7b1c84a2 + KeyboardSpy: edb2ab362c69d4b98b41b5a46b773e65209c2b87 + Material: 8265a77332acfb7872a7fd0f4f2023f080d25d1f + SnapKit: a42d492c16e80209130a3379f73596c3454b7694 -PODFILE CHECKSUM: 739236577b52ddde503122c640e7da8d72f1f960 +PODFILE CHECKSUM: 2b0ce6efee22339689fc03eb885c560a62beee10 -COCOAPODS: 1.1.0.rc.3 +COCOAPODS: 1.3.1 diff --git a/Example/Pods/Local Podspecs/KeyboardSpy.podspec.json b/Example/Pods/Local Podspecs/KeyboardSpy.podspec.json index a953670..6e98088 100644 --- a/Example/Pods/Local Podspecs/KeyboardSpy.podspec.json +++ b/Example/Pods/Local Podspecs/KeyboardSpy.podspec.json @@ -1,8 +1,8 @@ { "name": "KeyboardSpy", - "version": "0.1.0", - "summary": "A short description of KeyboardSpy.", - "description": "TODO: Add long description of the pod here.", + "version": "1.0", + "summary": "The Easiest Way to Observe Keyboard Notifications in iOS", + "description": "KeyboardSpy is a super lightweight and easy to use wrapper that makes observing keyboard notifications in iOS a breeze.", "homepage": "https://github.com/Daltron/KeyboardSpy", "license": { "type": "MIT", @@ -13,7 +13,7 @@ }, "source": { "git": "https://github.com/Daltron/KeyboardSpy.git", - "tag": "0.1.0" + "tag": "1.0" }, "platforms": { "ios": "8.0" diff --git a/Example/Pods/Local Podspecs/Material.podspec.json b/Example/Pods/Local Podspecs/Material.podspec.json new file mode 100644 index 0000000..7cc37b9 --- /dev/null +++ b/Example/Pods/Local Podspecs/Material.podspec.json @@ -0,0 +1,39 @@ +{ + "name": "Material", + "version": "3.0.0", + "license": "BSD-3-Clause", + "summary": "A Material Design library for creating beautiful applications.", + "homepage": "http://materialswift.com", + "social_media_url": "https://www.facebook.com/cosmicmindcom", + "authors": { + "CosmicMind, Inc.": "support@cosmicmind.com" + }, + "source": { + "git": "https://github.com/CosmicMind/Material.git", + "tag": "3.0.0" + }, + "default_subspecs": "Core", + "platforms": { + "ios": "8.0" + }, + "subspecs": [ + { + "name": "Core", + "platforms": { + "ios": "8.0" + }, + "ios": { + "source_files": "Sources/**/*.swift" + }, + "requires_arc": true, + "resource_bundles": { + "com.cosmicmind.material.icons": [ + "Sources/**/*.xcassets" + ], + "com.cosmicmind.material.fonts": [ + "Sources/**/*.ttf" + ] + } + } + ] +} diff --git a/Example/Pods/Manifest.lock b/Example/Pods/Manifest.lock index beabd7f..d11bcbb 100644 --- a/Example/Pods/Manifest.lock +++ b/Example/Pods/Manifest.lock @@ -1,13 +1,13 @@ PODS: - - KeyboardSpy (0.1.0) - - Material (2.4.11): - - Material/Core (= 2.4.11) - - Material/Core (2.4.11) - - SnapKit (3.1.2) + - KeyboardSpy (1.0) + - Material (2.10.2): + - Material/Core (= 2.10.2) + - Material/Core (2.10.2) + - SnapKit (4.0.0) DEPENDENCIES: - KeyboardSpy (from `../`) - - Material (~> 2.0) + - Material - SnapKit EXTERNAL SOURCES: @@ -15,10 +15,10 @@ EXTERNAL SOURCES: :path: ../ SPEC CHECKSUMS: - KeyboardSpy: 6162f98e3047f1350ac2b75036fa8025c5faa815 - Material: 09b50565d8f824bd74881eba12d7c549b41f510d - SnapKit: 12b24f569cb7c143acc9c22b9d91b23e7b1c84a2 + KeyboardSpy: edb2ab362c69d4b98b41b5a46b773e65209c2b87 + Material: 8265a77332acfb7872a7fd0f4f2023f080d25d1f + SnapKit: a42d492c16e80209130a3379f73596c3454b7694 -PODFILE CHECKSUM: 739236577b52ddde503122c640e7da8d72f1f960 +PODFILE CHECKSUM: 2b0ce6efee22339689fc03eb885c560a62beee10 -COCOAPODS: 1.1.0.rc.3 +COCOAPODS: 1.3.1 diff --git a/Example/Pods/Material/LICENSE.md b/Example/Pods/Material/LICENSE.md index 64e9c9e..5e2bba4 100644 --- a/Example/Pods/Material/LICENSE.md +++ b/Example/Pods/Material/LICENSE.md @@ -1,4 +1,4 @@ -Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . All rights reserved. +Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, 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: diff --git a/Example/Pods/Material/README.md b/Example/Pods/Material/README.md index fcae9a9..5e7352e 100644 --- a/Example/Pods/Material/README.md +++ b/Example/Pods/Material/README.md @@ -1,58 +1,50 @@ ![Material](http://www.cosmicmind.com/material/github/material-logo.png) -## Welcome to Material +# Material -Material is an animation and graphics framework that is used to create beautiful applications. +Welcome to **Material,** a Material Design library used to create beautiful applications. Material's animation system has been completely reworked to take advantage of [Motion](https://github.com/CosmicMind/Motion), a library dedicated to animations and transitions. -![Material Sample](http://cosmicmind.com/samples/github/page-tab-bar-controller-2.png) +[![Carthage compatible](https://img.shields.io/badge/Carthage-Compatible-brightgreen.svg?style=flat)](https://github.com/Carthage/Carthage) +[![Version](https://img.shields.io/cocoapods/v/Material.svg?style=flat)](http://cocoapods.org/pods/Material) +[![License](https://img.shields.io/cocoapods/l/Material.svg?style=flat)](https://github.com/lkzhao/Material/blob/master/LICENSE?raw=true) +![Xcode 8.2+](https://img.shields.io/badge/Xcode-8.2%2B-blue.svg) +![iOS 8.0+](https://img.shields.io/badge/iOS-8.0%2B-blue.svg) +![Swift 3.0+](https://img.shields.io/badge/Swift-3.0%2B-orange.svg) +[![Donate](https://img.shields.io/badge/Donate-PayPal-blue.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=9D6MURMLLUNQ2) -* [Download the latest sample](https://github.com/CosmicMind/Samples/tree/master/Graph/CardTableView). +## Photos Sample -## About Material 2 +Take a look at a sample [Photos](https://github.com/CosmicMind/Samples/tree/master/Projects/Programmatic/Photos) project to get started. -The first version of Material was to bring Material Design to iOS. We considered that a great starting point, but not the entire story. Material 2 is the next chapter, which goes deeper into iOS with refined APIs that simplify Architecture, Photo Library, Reminders, Text Editing, Photo & Video, and much more. In addition to Material Design, we love Apple’s flat UI. Having this in mind, we made it possible to accomplish both UI styles with ease. +![Photos](http://www.cosmicmind.com/motion/projects/photos.gif) -## Why A Separate Samples Repo? +## Sample Projects -We moved all sample projects to a separate repo named [Samples](https://github.com/CosmicMind/Samples) to allow their development to be independent of the Material framework. There has been instances where we needed to update the versions of the framework to accommodate changes that only occurred in the sample projects. +Take a look at [Sample Projects](https://github.com/CosmicMind/Samples) to get your projects started. ## Features - [x] Completely Customizable -- [x] Animations -- [x] Grid System -- [x] Layout Library +- [x] [Motion Animations & Transitions](https://github.com/CosmicMind/Motion) +- [x] Layout Tools for AutoLayout & Grid Systems - [x] Color Library -- [x] Photo Library -- [x] Photo & Video - [x] Cards -- [x] Menus +- [x] FABMenu - [x] Icons - [x] TextField - [X] Snackbar -- [x] TabBar -- [x] PageTabBar +- [x] Tabs +- [x] Chips - [X] SearchBar - [x] NavigationController - [x] NavigationDrawer - [x] BottomNavigationBar -- [x] Sample Projects -- [x] And More... - -## Releasing January 2017 - Material 2.5.0 - -- [x] Reminders -- [x] Text Editor -- [x] Toasts -- [x] Dialogs & Alerts -- [x] Bottom Sheets -- [x] Transitions -- [x] Updated Motion API +- [x] [Sample Projects](https://github.com/CosmicMind/Samples) - [x] And More... ## Requirements -* iOS 8.0+ / Mac OS X 10.9+ +* iOS 8.0+ * Xcode 8.0+ ## Communication @@ -65,20 +57,14 @@ We moved all sample projects to a separate repo named [Samples](https://github.c ## Installation -> **Embedded frameworks require a minimum deployment target of iOS 8 or OS X Mavericks (10.9).** +> **Embedded frameworks require a minimum deployment target of iOS 8+.** > - [Download Material](https://github.com/CosmicMind/Material/archive/master.zip) Visit the [Installation](https://github.com/CosmicMind/Material/wiki/Installation) page to learn how to install Material using [CocoaPods](http://cocoapods.org) and [Carthage](https://github.com/Carthage/Carthage). -## Changelog - -Material is a growing project and will encounter changes throughout its development. It is recommended that the [Changelog](https://github.com/CosmicMind/Material/wiki/Changelog) be reviewed prior to updating versions. +## Change Log -# Samples - -The following are samples to see how Material may be used within your applications. - -* Visit the [Samples](https://github.com/CosmicMind/Samples) repo to see sample projects using Graph. +Material is a growing project and will encounter changes throughout its development. It is recommended that the [Change Log](https://github.com/CosmicMind/Material/wiki/change_log) be reviewed prior to updating versions. ## Icons @@ -90,11 +76,11 @@ Icons is a library of Google and CosmicMind icons that are available for use wit ## Colors -Try the Material Colors app to see the wonderful colors available in Material, or use the online version at [MaterialColors.io](http://materialcolors.io). +Try the Material Colors app to see the wonderful colors available in Material, or use the online version at [MaterialColor.com](http://materialcolor.com). ![MaterialColors](http://www.cosmicmind.com/gifs/shared/colors.gif) -[Get Material Colors on the AppStore](https://itunes.apple.com/app/x/id1111994400?mt=8) +* [Material Colors iOS App](https://itunes.apple.com/app/x/id1111994400?mt=8) ## TextField @@ -102,9 +88,7 @@ A TextField is an excellent way to improve UX. It allows for a placeholder and a ![TextField](http://www.cosmicmind.com/gifs/white/text-field.gif) -* Download the complete [TextField sample](https://github.com/CosmicMind/Samples/tree/master/Material/Programmatic/TextField). -* Learn more about [TextField](http://cosmicmind.com/material/textfield). - +* [TextField Sample](https://github.com/CosmicMind/Samples/tree/master/Projects/Programmatic/TextField) ## Button @@ -112,9 +96,7 @@ A button is used to trigger an action through a touch event. Material comes with ![Material Image](http://www.cosmicmind.com/material/white/button.gif) -* Download the complete [Button sample](https://github.com/CosmicMind/Samples/tree/master/Material/Programmatic/Button). -* Learn more about [Button](http://cosmicmind.com/material/button). - +* [Button Sample](https://github.com/CosmicMind/Samples/tree/master/Projects/Programmatic/Button) ## Switch @@ -122,9 +104,7 @@ A switch is a control component that toggles between on and off states. ![Material Image](http://www.cosmicmind.com/material/white/switch.gif) -* Download the complete [Switch sample](https://github.com/CosmicMind/Samples/tree/master/Material/Programmatic/Switch). -* Learn more about [Switch](http://cosmicmind.com/material/switch). - +* [Switch Sample](https://github.com/CosmicMind/Samples/tree/master/Projects/Programmatic/Switch) ## Card @@ -132,40 +112,31 @@ A Card is a flexible component that may be configured in any way you like. It ha ![Material Image](http://www.cosmicmind.com/gifs/white/card.gif) -* Download the complete [Card sample](https://github.com/CosmicMind/Samples/tree/master/Material/Programmatic/Card). -* Learn more about [Card](http://cosmicmind.com/material/card). - +* [Card Sample](https://github.com/CosmicMind/Samples/tree/master/Projects/Programmatic/Card) ## ImageCard An ImageCard is an expansion of the base Card. The Toolbar overlays an image area that sits above the dynamic content area. -![Material Image](http://www.cosmicmind.com/gifs/white/image-card.gif) - -* Download the complete [ImageCard sample](https://github.com/CosmicMind/Samples/tree/master/Material/Programmatic/ImageCard). -* Learn more about [ImageCard](http://cosmicmind.com/material/imagecard). -* Learn how to make the ImageCard data-driven with [Graph's ImageCard sample](https://github.com/CosmicMind/Samples/tree/master/Graph/ImageCard). +![Image Card Sample](http://www.cosmicmind.com/gifs/white/image-card.gif) +* [ImageCard Sample](https://github.com/CosmicMind/Samples/tree/master/Projects/Programmatic/ImageCard) ## PresenterCard The PresenterCard is a completely new card style. It allows for a primary presentation area that may be any UIView type in addition to the content area, Toolbar, and Bar components. The options for this card are endless. -![Material Image](http://www.cosmicmind.com/gifs/white/presenter-card.gif) - -* Download the complete [PresenterCard sample](https://github.com/CosmicMind/Samples/tree/master/Material/Programmatic/PresenterCard). -* Learn more about [PresenterCard](http://cosmicmind.com/material/presentercard). +![Presenter Card Sample](http://www.cosmicmind.com/gifs/white/presenter-card.gif) +* [PresenterCard Sample](https://github.com/CosmicMind/Samples/tree/master/Projects/Programmatic/PresenterCard) -## Menu +## FABMenu -A Menu manages a collection of views. A new MenuItem type has been added that manages a title and button to improve UX and visual beauty. +A FABMenu manages a collection of views. A new MenuItem type has been added that manages a title and button to improve UX and visual beauty. ![Material Image](http://www.cosmicmind.com/material/white/menu-controller.gif) -* Download the complete [Menu sample](https://github.com/CosmicMind/Samples/tree/master/Material/Programmatic/MenuController). -* Learn more about [Menu](http://cosmicmind.com/material/menu). - +* [FABMenu Sample](https://github.com/CosmicMind/Samples/tree/master/Projects/Programmatic/FABMenuController) ## Toolbar @@ -173,30 +144,23 @@ Toolbars are super flexible and add excellent control to your navigation flow. T ![Material Image](http://www.cosmicmind.com/gifs/white/toolbar-controller.gif) -* Download the complete [Toolbar sample](https://github.com/CosmicMind/Samples/tree/master/Material/Programmatic/ToolbarController). -* Learn more about [Toolbar](http://cosmicmind.com/material/toolbar). - +* [Toolbar Sample](https://github.com/CosmicMind/Samples/tree/master/Projects/Programmatic/ToolbarController) ## SearchBar A SearchBar is a powerful navigation tool that allows for user's input with an instant visual response. A set of left and right views may be added to expand functionality. -![Material Image](http://www.cosmicmind.com/gifs/shared/search-bar-controller.gif) - -* Download the complete [SearchBar sample](https://github.com/CosmicMind/Samples/tree/master/Material/Programmatic/SearchBarController). -* Learn more about [SearchBar](http://cosmicmind.com/material/searchbar). -* Learn how to make the SearchBar data-driven with [Graph's Search sample](https://github.com/CosmicMind/Samples/tree/master/Graph/Search). +![SearchBarController](http://www.cosmicmind.com/gifs/shared/search-bar-controller.gif) +* [SearchBar Sample](https://github.com/CosmicMind/Samples/tree/master/Projects/Programmatic/Search) -## PageTabBar +## Tabs -A PageTabBar is a new component that links a customizable TabBar to a UIPageViewController making a powerful and visually pleasing component to have in any application. The TabBar can be aligned at the top or bottom of the view controller. +Tabs is a new component that links a customizable TabBar to a stack of view controllers making a powerful and visually pleasing component to have in any application. -![Material Image](http://www.cosmicmind.com/material/white/page-tab-bar-controller.gif) - -* Download the complete [PageTabBar sample](https://github.com/CosmicMind/Samples/tree/master/Material/Programmatic/PageTabBarController). -* Learn more about [PageTabBar](http://cosmicmind.com/material/pagetabbar). +![Tabs](http://www.cosmicmind.com/material/white/page-tab-bar-controller.gif) +* [Tabs Sample](https://github.com/CosmicMind/Samples/tree/master/Projects/Programmatic/TabsController) ## NavigationController @@ -204,9 +168,7 @@ A NavigationController is a specialized view controller that manages a hierarchy ![Material Image](http://www.cosmicmind.com/gifs/white/navigation-controller.gif) -* Download the complete [NavigationController sample](https://github.com/CosmicMind/Samples/tree/master/Material/Programmatic/NavigationController). -* Learn more about [NavigationController](http://cosmicmind.com/material/navigationcontroller). - +* [NavigationController Sample](https://github.com/CosmicMind/Samples/tree/master/Projects/Programmatic/NavigationController) ## NavigationDrawer @@ -214,9 +176,7 @@ A NavigationDrawer slides in from the left or right and contains the navigation ![Material Image](http://www.cosmicmind.com/material/shared/navigation-drawer-controller.gif) -* Download the complete [NavigationDrawer sample](https://github.com/CosmicMind/Samples/tree/master/Material/Programmatic/NavigationDrawerController). -* Learn more about [NavigationDrawer](http://cosmicmind.com/material/navigationdrawer). - +* [NavigationDrawer Sample](https://github.com/CosmicMind/Samples/tree/master/Projects/Programmatic/NavigationDrawerController) ## Snackbar @@ -224,29 +184,7 @@ A Snackbar is a new component that is very simple in its behavior and very power ![Material Image](http://www.cosmicmind.com/material/white/snackbar-controller.gif) -* Download the complete [Snackbar sample](https://github.com/CosmicMind/Samples/tree/master/Material/Programmatic/SnackbarController). -* Learn more about [Snackbar](http://cosmicmind.com/material/snackbar). - - -## PhotoLibrary - -PhotoLibrary is a new component that simplifies the Photos framework and allows for beautiful photos found in the Photos application to be used within your application. - -![Material Image](http://www.cosmicmind.com/material/shared/photolibrary-controller.png) - -* Download the complete [PhotoLibrary sample](https://github.com/CosmicMind/Samples/tree/master/Material/Programmatic/PhotoLibraryController). -* Learn more about [PhotoLibrary](http://cosmicmind.com/material/photolibrary). - - -## Capture - -Capture is an API that simplifies iOS' AVFoundation framework. It allows for photos and video to easily be captured while managing all the complexities. - -![Material Image](http://www.cosmicmind.com/material/shared/capture-controller.png) - -* Download the complete [Capture sample](https://github.com/CosmicMind/Samples/tree/master/Material/Programmatic/CaptureController). -* Learn more about [Capture](http://cosmicmind.com/material/capture). - +* [Snackbar Sample](https://github.com/CosmicMind/Samples/tree/master/Projects/Programmatic/SnackbarController) ## Sticker Sheet @@ -254,8 +192,7 @@ To help template your project, checkout Material Sticker Sheet. ![MaterialStickerSheet](http://www.cosmicmind.com/MK/material_iso_1.png) -[Get Material Sticker Sheet](http://www.materialup.com/posts/material-design-sticker-sheets) - +* [Material Sticker Sheet](http://www.materialup.com/posts/material-design-sticker-sheets) ## Much More... @@ -263,7 +200,7 @@ So much more inside. Enjoy! ## License -Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . All rights reserved. +Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, 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: diff --git a/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Animator/MotionAnimator.swift b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Animator/MotionAnimator.swift new file mode 100644 index 0000000..94cf7f9 --- /dev/null +++ b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Animator/MotionAnimator.swift @@ -0,0 +1,75 @@ +/* + * The MIT License (MIT) + * + * Copyright (C) 2017, Daniel Dahan and CosmicMind, Inc. . + * All rights reserved. + * + * Original Inspiration & Author + * Copyright (c) 2016 Luke Zhao + * + * 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 UIKit + +public protocol MotionAnimator: class { + /// A reference to a MotionContext. + weak var context: MotionContext! { get set } + + /// Cleans the contexts. + func clean() + + /** + A function that determines if a view can be animated. + - Parameter view: A UIView. + - Parameter isAppearing: A boolean that determines whether the + view is appearing. + */ + func canAnimate(view: UIView, isAppearing: Bool) -> Bool + + /** + Animates the fromViews to the toViews. + - Parameter fromViews: An Array of UIViews. + - Parameter toViews: An Array of UIViews. + - Returns: A TimeInterval. + */ + func animate(fromViews: [UIView], toViews: [UIView]) -> TimeInterval + + /** + Moves the view's animation to the given elapsed time. + - Parameter to elapsedTime: A TimeInterval. + */ + func seek(to elapsedTime: TimeInterval) + + /** + Resumes the animation with a given elapsed time and + optional reversed boolean. + - Parameter at elapsedTime: A TimeInterval. + - Parameter isReversed: A boolean to reverse the animation + or not. + */ + func resume(at elapsedTime: TimeInterval, isReversed: Bool) -> TimeInterval + + /** + Applies the given state to the given view. + - Parameter state: A MotionTransitionState. + - Parameter to view: A UIView. + */ + func apply(state: MotionTransitionState, to view: UIView) +} diff --git a/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Animator/MotionAnimatorViewContext.swift b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Animator/MotionAnimatorViewContext.swift new file mode 100644 index 0000000..befe954 --- /dev/null +++ b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Animator/MotionAnimatorViewContext.swift @@ -0,0 +1,110 @@ +/* + * The MIT License (MIT) + * + * Copyright (C) 2017, Daniel Dahan and CosmicMind, Inc. . + * All rights reserved. + * + * Original Inspiration & Author + * Copyright (c) 2016 Luke Zhao + * + * 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 UIKit + +internal class MotionAnimatorViewContext { + /// An optional reference to a MotionAnimator. + var animator: MotionAnimator? + + /// A reference to the snapshot UIView. + var snapshot: UIView + + /// Animation duration time. + var duration: TimeInterval = 0 + + /// The animation target state. + var targetState: MotionTransitionState + + /// The computed current time of the snapshot layer. + var currentTime: TimeInterval { + return snapshot.layer.convertTime(CACurrentMediaTime(), from: nil) + } + + /// A container view for the transition. + var container: UIView? { + return animator?.context.container + } + + /** + An initializer. + - Parameter animator: A MotionAnimator. + - Parameter snapshot: A UIView. + - Parameter targetState: A MotionTransitionState. + */ + required init(animator: MotionAnimator, snapshot: UIView, targetState: MotionTransitionState) { + self.animator = animator + self.snapshot = snapshot + self.targetState = targetState + } + + /// Cleans the context. + func clean() { + animator = nil + } + + /** + A class function that determines if a view can be animated + to a given state. + - Parameter view: A UIView. + - Parameter state: A MotionTransitionState. + - Parameter isAppearing: A boolean that determines whether the + view is appearing. + */ + class func canAnimate(view: UIView, state: MotionTransitionState, isAppearing: Bool) -> Bool { + return false + } + + /** + Resumes the animation with a given elapsed time and + optional reversed boolean. + - Parameter at elapsedTime: A TimeInterval. + - Parameter isReversed: A boolean to reverse the animation + or not. + */ + func resume(at elapsedTime: TimeInterval, isReversed: Bool) {} + + /** + Moves the animation to the given elapsed time. + - Parameter to elapsedTime: A TimeInterval. + */ + func seek(to elapsedTime: TimeInterval) {} + + /** + Applies the given state to the target state. + - Parameter state: A MotionTransitionState. + */ + func apply(state: MotionTransitionState) {} + + /** + Starts the animations with an appearing boolean flag. + - Parameter isAppearing: A boolean value whether the view + is appearing or not. + */ + func startAnimations(isAppearing: Bool) {} +} diff --git a/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Animator/MotionCoreAnimationViewContext.swift b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Animator/MotionCoreAnimationViewContext.swift new file mode 100644 index 0000000..58e88ea --- /dev/null +++ b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Animator/MotionCoreAnimationViewContext.swift @@ -0,0 +1,427 @@ +/* + * The MIT License (MIT) + * + * Copyright (C) 2017, Daniel Dahan and CosmicMind, Inc. . + * All rights reserved. + * + * Original Inspiration & Author + * Copyright (c) 2016 Luke Zhao + * + * 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 UIKit + +internal class MotionCoreAnimationViewContext: MotionAnimatorViewContext { + /// The transition states. + fileprivate var transitionStates = [String: (Any?, Any?)]() + + /// A reference to the animation timing function. + fileprivate var timingFunction = CAMediaTimingFunction.standard + + /// Layer which holds the content. + fileprivate var contentLayer: CALayer? { + return snapshot.layer.sublayers?.get(0) + } + + /// Layer which holds the overlay. + fileprivate var overlayLayer: CALayer? + + override func clean() { + super.clean() + overlayLayer = nil + } + + override class func canAnimate(view: UIView, state: MotionTransitionState, isAppearing: Bool) -> Bool { + return nil != state.position || + nil != state.size || + nil != state.transform || + nil != state.cornerRadius || + nil != state.opacity || + nil != state.overlay || + nil != state.backgroundColor || + nil != state.borderColor || + nil != state.borderWidth || + nil != state.shadowOpacity || + nil != state.shadowRadius || + nil != state.shadowOffset || + nil != state.shadowColor || + nil != state.shadowPath || + nil != state.contentsRect || + state.forceAnimate + } + + override func apply(state: MotionTransitionState) { + let ts = viewState(targetState: state) + + for (key, targetValue) in ts { + if nil == transitionStates[key] { + let current = currentValue(for: key) + transitionStates[key] = (current, current) + } + + animate(key: key, beginTime: 0, fromValue: targetValue, toValue: targetValue) + } + } + + override func resume(at elapsedTime: TimeInterval, isReversed: Bool) { + for (key, (fromValue, toValue)) in transitionStates { + transitionStates[key] = (currentValue(for: key), !isReversed ? toValue : fromValue) + } + + targetState.duration = isReversed ? elapsedTime - targetState.delay : duration - elapsedTime + animate(delay: max(0, targetState.delay - elapsedTime)) + } + + override func seek(to elapsedTime: TimeInterval) { + seek(layer: snapshot.layer, elapsedTime: elapsedTime) + + if let v = contentLayer { + seek(layer: v, elapsedTime: elapsedTime) + } + + if let v = overlayLayer { + seek(layer: v, elapsedTime: elapsedTime) + } + } + + override func startAnimations(isAppearing: Bool) { + if let beginState = targetState.beginState?.state { + let appeared = viewState(targetState: beginState) + for (k, v) in appeared { + snapshot.layer.setValue(v, forKeyPath: k) + } + + if let (k, v) = beginState.overlay { + let overlay = getOverlayLayer() + overlay.backgroundColor = k + overlay.opacity = Float(v) + } + } + + let disappeared = viewState(targetState: targetState) + for (k, v) in disappeared { + let isAppearingState = currentValue(for: k) + let toValue = isAppearing ? isAppearingState : v + let fromValue = !isAppearing ? isAppearingState : v + + transitionStates[k] = (fromValue, toValue) + } + + animate(delay: targetState.delay) + } +} + +extension MotionCoreAnimationViewContext { + /** + Lazy loads the overlay layer. + - Returns: A CALayer. + */ + fileprivate func getOverlayLayer() -> CALayer { + if nil == overlayLayer { + overlayLayer = CALayer() + overlayLayer!.frame = snapshot.bounds + overlayLayer!.opacity = 0 + snapshot.layer.addSublayer(overlayLayer!) + } + + return overlayLayer! + } + + /** + Retrieves the overlay key for a given key. + - Parameter for key: A String. + - Returns: An optional String. + */ + fileprivate func overlayKey(for key: String) -> String? { + guard key.hasPrefix("overlay.") else { + return nil + } + + var k = key + k.removeSubrange(k.startIndex.. Any? { + if let key = overlayKey(for: key) { + return overlayLayer?.value(forKeyPath: key) + } + + if false != snapshot.layer.animationKeys()?.isEmpty { + return snapshot.layer.value(forKeyPath:key) + } + + return (snapshot.layer.presentation() ?? snapshot.layer).value(forKeyPath: key) + } + + /** + Retrieves the animation for a given key. + - Parameter key: String. + - Parameter beginTime: A TimeInterval. + - Parameter fromValue: An optional Any value. + - Parameter toValue: An optional Any value. + - Parameter ignoreArc: A Boolean value to ignore an arc position. + */ + fileprivate func getAnimation(key: String, beginTime: TimeInterval, fromValue: Any?, toValue: Any?, ignoreArc: Bool = false) -> CAPropertyAnimation { + let key = overlayKey(for: key) ?? key + let anim: CAPropertyAnimation + + if !ignoreArc, "position" == key, let arcIntensity = targetState.arc, + let fromPos = (fromValue as? NSValue)?.cgPointValue, + let toPos = (toValue as? NSValue)?.cgPointValue, + abs(fromPos.x - toPos.x) >= 1, abs(fromPos.y - toPos.y) >= 1 { + + let a = CAKeyframeAnimation(keyPath: key) + let path = CGMutablePath() + let maxControl = fromPos.y > toPos.y ? CGPoint(x: toPos.x, y: fromPos.y) : CGPoint(x: fromPos.x, y: toPos.y) + let minControl = (toPos - fromPos) / 2 + fromPos + + path.move(to: fromPos) + path.addQuadCurve(to: toPos, control: minControl + (maxControl - minControl) * arcIntensity) + + a.values = [fromValue!, toValue!] + a.path = path + a.duration = duration + a.timingFunctions = [timingFunction] + + anim = a + } else if #available(iOS 9.0, *), "cornerRadius" != key, let (stiffness, damping) = targetState.spring { + let a = CASpringAnimation(keyPath: key) + a.stiffness = stiffness + a.damping = damping + a.duration = a.settlingDuration * 0.9 + a.fromValue = fromValue + a.toValue = toValue + + anim = a + } else { + let a = CABasicAnimation(keyPath: key) + a.duration = duration + a.fromValue = fromValue + a.toValue = toValue + a.timingFunction = timingFunction + + anim = a + } + + anim.fillMode = kCAFillModeBoth + anim.isRemovedOnCompletion = false + anim.beginTime = beginTime + + return anim + } + + /** + Retrieves the duration of an animation, including the + duration of the animation and the initial delay. + - Parameter key: A String. + - Parameter beginTime: A TimeInterval. + - Parameter fromValue: A optional Any value. + - Parameter toValue: A optional Any value. + - Returns: A TimeInterval. + */ + @discardableResult + fileprivate func animate(key: String, beginTime: TimeInterval, fromValue: Any?, toValue: Any?) -> TimeInterval { + let anim = getAnimation(key: key, beginTime:beginTime, fromValue: fromValue, toValue: toValue) + + if let overlayKey = overlayKey(for: key) { + getOverlayLayer().add(anim, forKey: overlayKey) + + } else { + snapshot.layer.add(anim, forKey: key) + + switch key { + case "cornerRadius", "contentsRect", "contentsScale": + contentLayer?.add(anim, forKey: key) + overlayLayer?.add(anim, forKey: key) + + case "bounds.size": + guard let fs = (fromValue as? NSValue)?.cgSizeValue else { + return 0 + } + + guard let ts = (toValue as? NSValue)?.cgSizeValue else { + return 0 + } + + // for the snapshotView(UIReplicantView): there is a + // subview(UIReplicantContentView) that is hosting the real snapshot image. + // because we are using CAAnimations and not UIView animations, + // The snapshotView will not layout during animations. + // we have to add two more animations to manually layout the content view. + let fpn = NSValue(cgPoint: fs.center) + let tpn = NSValue(cgPoint: ts.center) + + let a = getAnimation(key: "position", beginTime: 0, fromValue: fpn, toValue: tpn, ignoreArc: true) + a.beginTime = anim.beginTime + a.timingFunction = anim.timingFunction + a.duration = anim.duration + + contentLayer?.add(a, forKey: "position") + contentLayer?.add(anim, forKey: key) + + overlayLayer?.add(a, forKey: "position") + overlayLayer?.add(anim, forKey: key) + + default: break + } + } + + return anim.duration + anim.beginTime - beginTime + } + + /** + Animates the contentLayer and overlayLayer with a given delay. + - Parameter delay: A TimeInterval. + */ + fileprivate func animate(delay: TimeInterval) { + if let v = targetState.timingFunction { + timingFunction = v + } + + if let v = targetState.duration { + duration = v + } + + let beginTime = currentTime + delay + + var finalDuration: TimeInterval = duration + + for (key, (fromValue, toValue)) in transitionStates { + let neededTime = animate(key: key, beginTime: beginTime, fromValue: fromValue, toValue: toValue) + finalDuration = max(finalDuration, neededTime + delay) + } + + duration = finalDuration + } + + /** + Constructs a map of key paths to animation state values. + - Parameter targetState state: A MotionTransitionState. + - Returns: A map of key paths to animation values. + */ + fileprivate func viewState(targetState ts: MotionTransitionState) -> [String: Any?] { + var ts = ts + var values = [String: Any?]() + + if let size = ts.size { + if ts.useScaleBasedSizeChange ?? targetState.useScaleBasedSizeChange ?? false { + let currentSize = snapshot.bounds.size + ts.append(.scale(x: size.width / currentSize.width, y: size.height / currentSize.height)) + + } else { + values["bounds.size"] = NSValue(cgSize:size) + } + } + + if let position = ts.position { + values["position"] = NSValue(cgPoint:position) + } + + if let opacity = ts.opacity, !(snapshot is UIVisualEffectView) { + values["opacity"] = NSNumber(value: opacity) + } + + if let cornerRadius = ts.cornerRadius { + values["cornerRadius"] = NSNumber(value: cornerRadius.native) + } + + if let backgroundColor = ts.backgroundColor { + values["backgroundColor"] = backgroundColor + } + + if let zPosition = ts.zPosition { + values["zPosition"] = NSNumber(value: zPosition.native) + } + + if let borderWidth = ts.borderWidth { + values["borderWidth"] = NSNumber(value: borderWidth.native) + } + + if let borderColor = ts.borderColor { + values["borderColor"] = borderColor + } + + if let masksToBounds = ts.masksToBounds { + values["masksToBounds"] = masksToBounds + } + + if ts.displayShadow { + if let shadowColor = ts.shadowColor { + values["shadowColor"] = shadowColor + } + + if let shadowRadius = ts.shadowRadius { + values["shadowRadius"] = NSNumber(value: shadowRadius.native) + } + + if let shadowOpacity = ts.shadowOpacity { + values["shadowOpacity"] = NSNumber(value: shadowOpacity) + } + + if let shadowPath = ts.shadowPath { + values["shadowPath"] = shadowPath + } + + if let shadowOffset = ts.shadowOffset { + values["shadowOffset"] = NSValue(cgSize: shadowOffset) + } + } + + if let contentsRect = ts.contentsRect { + values["contentsRect"] = NSValue(cgRect: contentsRect) + } + + if let contentsScale = ts.contentsScale { + values["contentsScale"] = NSNumber(value: contentsScale.native) + } + + if let transform = ts.transform { + values["transform"] = NSValue(caTransform3D: transform) + } + + if let (color, opacity) = ts.overlay { + values["overlay.backgroundColor"] = color + values["overlay.opacity"] = NSNumber(value: opacity.native) + } + + return values + } + + /** + Moves a layer's animation to a given elapsed time. + - Parameter layer: A CALayer. + - Parameter elapsedTime: A TimeInterval. + */ + fileprivate func seek(layer: CALayer, elapsedTime: TimeInterval) { + let timeOffset = elapsedTime - targetState.delay + for (key, anim) in layer.animations { + anim.speed = 0 + anim.timeOffset = max(0, min(anim.duration - 0.01, timeOffset)) + layer.removeAnimation(forKey: key) + layer.add(anim, forKey: key) + } + } +} diff --git a/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Animator/MotionHasInsertOrder.swift b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Animator/MotionHasInsertOrder.swift new file mode 100644 index 0000000..7e940bd --- /dev/null +++ b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Animator/MotionHasInsertOrder.swift @@ -0,0 +1,32 @@ +/* + * The MIT License (MIT) + * + * Copyright (C) 2017, Daniel Dahan and CosmicMind, Inc. . + * All rights reserved. + * + * Original Inspiration & Author + * Copyright (c) 2016 Luke Zhao + * + * 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. + */ + +internal protocol MotionHasInsertOrder: class { + /// A boolean indicating whether to insert the toView first or not. + var insertToViewFirst: Bool { get set } +} diff --git a/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Animator/MotionTransitionAnimator.swift b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Animator/MotionTransitionAnimator.swift new file mode 100644 index 0000000..b1fe8bf --- /dev/null +++ b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Animator/MotionTransitionAnimator.swift @@ -0,0 +1,158 @@ +/* + * The MIT License (MIT) + * + * Copyright (C) 2017, Daniel Dahan and CosmicMind, Inc. . + * All rights reserved. + * + * Original Inspiration & Author + * Copyright (c) 2016 Luke Zhao + * + * 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 UIKit + +internal class MotionTransitionAnimator: MotionAnimator, MotionHasInsertOrder { + /// A reference to a MotionContext. + weak public var context: MotionContext! + + /// An index of views to their corresponding animator context. + var viewToContexts = [UIView: T]() + + var insertToViewFirst = false +} + +extension MotionTransitionAnimator { + /** + Animates a given view. + - Parameter view: A UIView. + - Parameter isAppearing: A boolean that determines whether the + view is appearing. + */ + fileprivate func animate(view: UIView, isAppearing: Bool) { + let s = context.snapshotView(for: view) + let v = T(animator: self, snapshot: s, targetState: context[view]!) + + viewToContexts[view] = v + + v.startAnimations(isAppearing: isAppearing) + } +} + +extension MotionTransitionAnimator { + /// Cleans the contexts. + func clean() { + for v in viewToContexts.values { + v.clean() + } + + viewToContexts.removeAll() + insertToViewFirst = false + } + + /** + A function that determines if a view can be animated. + - Parameter view: A UIView. + - Parameter isAppearing: A boolean that determines whether the + view is appearing. + */ + func canAnimate(view: UIView, isAppearing: Bool) -> Bool { + guard let state = context[view] else { + return false + } + + return T.canAnimate(view: view, state: state, isAppearing: isAppearing) + } + + /** + Animates the fromViews to the toViews. + - Parameter fromViews: An Array of UIViews. + - Parameter toViews: An Array of UIViews. + - Returns: A TimeInterval. + */ + func animate(fromViews: [UIView], toViews: [UIView]) -> TimeInterval { + var duration: TimeInterval = 0 + + if insertToViewFirst { + for v in toViews { + animate(view: v, isAppearing: true) + } + + for v in fromViews { + animate(view: v, isAppearing: false) + } + + } else { + for v in fromViews { + animate(view: v, isAppearing: false) + } + + for v in toViews { + animate(view: v, isAppearing: true) + } + } + + for v in viewToContexts.values { + duration = max(duration, v.duration) + } + + return duration + } + + /** + Moves the view's animation to the given elapsed time. + - Parameter to elapsedTime: A TimeInterval. + */ + func seek(to elapsedTime: TimeInterval) { + for v in viewToContexts.values { + v.seek(to: elapsedTime) + } + } + + /** + Resumes the animation with a given elapsed time and + optional reversed boolean. + - Parameter at elapsedTime: A TimeInterval. + - Parameter isReversed: A boolean to reverse the animation + or not. + */ + func resume(at elapsedTime: TimeInterval, isReversed: Bool) -> TimeInterval { + var duration: TimeInterval = 0 + + for (_, v) in viewToContexts { + v.resume(at: elapsedTime, isReversed: isReversed) + duration = max(duration, v.duration) + } + + return duration + } + + /** + Applies the given state to the given view. + - Parameter state: A MotionTransitionState. + - Parameter to view: A UIView. + */ + func apply(state: MotionTransitionState, to view: UIView) { + guard let v = viewToContexts[view] else { + return + } + + v.apply(state: state) + } +} diff --git a/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Animator/MotionViewPropertyViewContext.swift b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Animator/MotionViewPropertyViewContext.swift new file mode 100644 index 0000000..2f625e2 --- /dev/null +++ b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Animator/MotionViewPropertyViewContext.swift @@ -0,0 +1,72 @@ +/* + * The MIT License (MIT) + * + * Copyright (C) 2017, Daniel Dahan and CosmicMind, Inc. . + * All rights reserved. + * + * Original Inspiration & Author + * Copyright (c) 2016 Luke Zhao + * + * 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 UIKit + +@available(iOS 10, tvOS 10, *) +internal class MotionViewPropertyViewContext: MotionAnimatorViewContext { + /// A reference to the UIViewPropertyAnimator. + fileprivate var viewPropertyAnimator: UIViewPropertyAnimator? + + override class func canAnimate(view: UIView, state: MotionTransitionState, isAppearing: Bool) -> Bool { + return view is UIVisualEffectView && nil != state.opacity + } + + override func resume(at elapsedTime: TimeInterval, isReversed: Bool) { + viewPropertyAnimator?.finishAnimation(at: isReversed ? .start : .end) + } + + override func seek(to elapsedTime: TimeInterval) { + viewPropertyAnimator?.pauseAnimation() + viewPropertyAnimator?.fractionComplete = CGFloat(elapsedTime / duration) + } + + override func clean() { + super.clean() + viewPropertyAnimator?.stopAnimation(true) + viewPropertyAnimator = nil + } + + override func startAnimations(isAppearing: Bool) { + guard let v = snapshot as? UIVisualEffectView else { + return + } + + let appearedEffect = v.effect + let disappearedEffect = 0 == targetState.opacity ? nil : v.effect + v.effect = isAppearing ? disappearedEffect : appearedEffect + + duration = targetState.duration! + + viewPropertyAnimator = UIViewPropertyAnimator(duration: duration, curve: .easeInOut) { + v.effect = isAppearing ? appearedEffect : disappearedEffect + } + + viewPropertyAnimator?.startAnimation() + } +} diff --git a/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Extensions/Motion+Array.swift b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Extensions/Motion+Array.swift new file mode 100644 index 0000000..7ec55fc --- /dev/null +++ b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Extensions/Motion+Array.swift @@ -0,0 +1,43 @@ +/* + * The MIT License (MIT) + * + * Copyright (C) 2017, Daniel Dahan and CosmicMind, Inc. . + * All rights reserved. + * + * Original Inspiration & Author + * Copyright (c) 2016 Luke Zhao + * + * 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 UIKit + +internal extension Array { + /** + Retrieves the element at the given index if it exists. + - Parameter _ index: An Int. + - Returns: An optional Element value. + */ + func get(_ index: Int) -> Element? { + if index < count { + return self[index] + } + return nil + } +} diff --git a/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Extensions/Motion+CALayer.swift b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Extensions/Motion+CALayer.swift new file mode 100644 index 0000000..646136b --- /dev/null +++ b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Extensions/Motion+CALayer.swift @@ -0,0 +1,288 @@ +/* + * The MIT License (MIT) + * + * Copyright (C) 2017, Daniel Dahan and CosmicMind, Inc. . + * 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 UIKit + +@available(iOS 10, *) +extension CALayer: CAAnimationDelegate {} + +internal extension CALayer { + /// Retrieves all currently running animations for the layer. + var animations: [(String, CAAnimation)] { + guard let keys = animationKeys() else { + return [] + } + + return keys.map { + return ($0, self.animation(forKey: $0)!.copy() as! CAAnimation) + } + } +} + +public extension CALayer { + /** + A function that accepts CAAnimation objects and executes them on the + view's backing layer. + - Parameter animation: A CAAnimation instance. + */ + func animate(_ animations: CAAnimation...) { + animate(animations) + } + + /** + A function that accepts CAAnimation objects and executes them on the + view's backing layer. + - Parameter animation: A CAAnimation instance. + */ + func animate(_ animations: [CAAnimation]) { + for animation in animations { + if nil == animation.delegate { + animation.delegate = self + } + + if let a = animation as? CABasicAnimation { + a.fromValue = (presentation() ?? self).value(forKeyPath: a.keyPath!) + } + + if let a = animation as? CAPropertyAnimation { + add(a, forKey: a.keyPath!) + } else if let a = animation as? CAAnimationGroup { + add(a, forKey: nil) + } else if let a = animation as? CATransition { + add(a, forKey: kCATransition) + } + } + } + + /** + Executed when an animation has started. + - Parameter _ anim: A CAAnimation. + */ + func animationDidStart(_ anim: CAAnimation) {} + + /** + A delegation function that is executed when the backing layer stops + running an animation. + - Parameter animation: The CAAnimation instance that stopped running. + - Parameter flag: A boolean that indicates if the animation stopped + because it was completed or interrupted. True if completed, false + if interrupted. + */ + func animationDidStop(_ anim: CAAnimation, finished flag: Bool) { + guard let a = anim as? CAPropertyAnimation else { + if let a = (anim as? CAAnimationGroup)?.animations { + for x in a { + animationDidStop(x, finished: true) + } + } + return + } + + guard let b = a as? CABasicAnimation else { + return + } + + guard let v = b.toValue else { + return + } + + guard let k = b.keyPath else { + return + } + + setValue(v, forKeyPath: k) + removeAnimation(forKey: k) + } + + /** + A function that accepts a list of MotionAnimation values and executes them. + - Parameter animations: A list of MotionAnimation values. + */ + func animate(_ animations: MotionAnimation...) { + animate(animations) + } + + /** + A function that accepts an Array of MotionAnimation values and executes them. + - Parameter animations: An Array of MotionAnimation values. + - Parameter completion: An optional completion block. + */ + func animate(_ animations: [MotionAnimation], completion: (() -> Void)? = nil) { + startAnimations(animations, completion: completion) + } +} + +fileprivate extension CALayer { + /** + A function that executes an Array of MotionAnimation values. + - Parameter _ animations: An Array of MotionAnimations. + - Parameter completion: An optional completion block. + */ + func startAnimations(_ animations: [MotionAnimation], completion: (() -> Void)? = nil) { + let ts = MotionAnimationState(animations: animations) + + Motion.delay(ts.delay) { [weak self, + ts = ts, + completion = completion] in + + guard let s = self else { + return + } + + var anims = [CABasicAnimation]() + var duration = 0 == ts.duration ? 0.01 : ts.duration + + if let v = ts.backgroundColor { + let a = MotionCAAnimation.background(color: UIColor(cgColor: v)) + a.fromValue = s.backgroundColor + anims.append(a) + } + + if let v = ts.borderColor { + let a = MotionCAAnimation.border(color: UIColor(cgColor: v)) + a.fromValue = s.borderColor + anims.append(a) + } + + if let v = ts.borderWidth { + let a = MotionCAAnimation.border(width: v) + a.fromValue = NSNumber(floatLiteral: Double(s.borderWidth)) + anims.append(a) + } + + if let v = ts.cornerRadius { + let a = MotionCAAnimation.corner(radius: v) + a.fromValue = NSNumber(floatLiteral: Double(s.cornerRadius)) + anims.append(a) + } + + if let v = ts.transform { + let a = MotionCAAnimation.transform(v) + a.fromValue = NSValue(caTransform3D: s.transform) + anims.append(a) + } + + if let v = ts.spin { + var a = MotionCAAnimation.spin(x: v.x) + a.fromValue = NSNumber(floatLiteral: 0) + anims.append(a) + + a = MotionCAAnimation.spin(y: v.y) + a.fromValue = NSNumber(floatLiteral: 0) + anims.append(a) + + a = MotionCAAnimation.spin(z: v.z) + a.fromValue = NSNumber(floatLiteral: 0) + anims.append(a) + } + + if let v = ts.position { + let a = MotionCAAnimation.position(v) + a.fromValue = NSValue(cgPoint: s.position) + anims.append(a) + } + + if let v = ts.opacity { + let a = MotionCAAnimation.fade(v) + a.fromValue = s.value(forKeyPath: MotionAnimationKeyPath.opacity.rawValue) ?? NSNumber(floatLiteral: 1) + anims.append(a) + } + + if let v = ts.zPosition { + let a = MotionCAAnimation.zPosition(v) + a.fromValue = s.value(forKeyPath: MotionAnimationKeyPath.zPosition.rawValue) ?? NSNumber(floatLiteral: 0) + anims.append(a) + } + + if let v = ts.size { + let a = MotionCAAnimation.size(v) + a.fromValue = NSValue(cgSize: s.bounds.size) + anims.append(a) + } + + if let v = ts.shadowPath { + let a = MotionCAAnimation.shadow(path: v) + a.fromValue = s.shadowPath + anims.append(a) + } + + if let v = ts.shadowColor { + let a = MotionCAAnimation.shadow(color: UIColor(cgColor: v)) + a.fromValue = s.shadowColor + anims.append(a) + } + + if let v = ts.shadowOffset { + let a = MotionCAAnimation.shadow(offset: v) + a.fromValue = NSValue(cgSize: s.shadowOffset) + anims.append(a) + } + + if let v = ts.shadowOpacity { + let a = MotionCAAnimation.shadow(opacity: v) + a.fromValue = NSNumber(floatLiteral: Double(s.shadowOpacity)) + anims.append(a) + } + + if let v = ts.shadowRadius { + let a = MotionCAAnimation.shadow(radius: v) + a.fromValue = NSNumber(floatLiteral: Double(s.shadowRadius)) + anims.append(a) + } + + if #available(iOS 9.0, *), let (stiffness, damping) = ts.spring { + for i in 0.. duration { + duration = a.settlingDuration + } + } + } + + let g = Motion.animate(group: anims, duration: duration) + g.fillMode = MotionAnimationFillModeToValue(mode: .both) + g.isRemovedOnCompletion = false + g.timingFunction = ts.timingFunction + + s.animate(g) + + if let v = ts.completion { + Motion.delay(duration, execute: v) + } + + if let v = completion { + Motion.delay(duration, execute: v) + } + } + } +} diff --git a/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Extensions/Motion+CAMediaTimingFunction.swift b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Extensions/Motion+CAMediaTimingFunction.swift new file mode 100644 index 0000000..973644f --- /dev/null +++ b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Extensions/Motion+CAMediaTimingFunction.swift @@ -0,0 +1,46 @@ +/* + * The MIT License (MIT) + * + * Copyright (C) 2017, Daniel Dahan and CosmicMind, Inc. . + * All rights reserved. + * + * Original Inspiration & Author + * Copyright (c) 2016 Luke Zhao + * + * 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 UIKit + +public extension CAMediaTimingFunction { + // Default + static let linear = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear) + static let easeIn = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn) + static let easeOut = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut) + static let easeInOut = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut) + + // Material + static let standard = CAMediaTimingFunction(controlPoints: 0.4, 0.0, 0.2, 1.0) + static let deceleration = CAMediaTimingFunction(controlPoints: 0.0, 0.0, 0.2, 1) + static let acceleration = CAMediaTimingFunction(controlPoints: 0.4, 0.0, 1, 1) + static let sharp = CAMediaTimingFunction(controlPoints: 0.4, 0.0, 0.6, 1) + + // Easing.net + static let easeOutBack = CAMediaTimingFunction(controlPoints: 0.175, 0.885, 0.32, 1.75) +} diff --git a/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Extensions/Motion+CG.swift b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Extensions/Motion+CG.swift new file mode 100644 index 0000000..e15b173 --- /dev/null +++ b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Extensions/Motion+CG.swift @@ -0,0 +1,296 @@ +/* + * The MIT License (MIT) + * + * Copyright (C) 2017, Daniel Dahan and CosmicMind, Inc. . + * All rights reserved. + * + * Original Inspiration & Author + * Copyright (c) 2016 Luke Zhao + * + * 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 MetalKit + +extension CGSize { + /// THe center point based on width and height. + var center: CGPoint { + return CGPoint(x: width / 2, y: height / 2) + } + + /// Top left point based on the size. + var topLeft: CGPoint { + return .zero + } + + /// Top right point based on the size. + var topRight: CGPoint { + return CGPoint(x: width, y: 0) + } + + /// Bottom left point based on the size. + var bottomLeftPoint: CGPoint { + return CGPoint(x: 0, y: height) + } + + /// Bottom right point based on the size. + var bottomRight: CGPoint { + return CGPoint(x: width, y: height) + } + + /** + Retrieves the size based on a given CGAffineTransform. + - Parameter _ t: A CGAffineTransform. + - Returns: A CGSize. + */ + func transform(_ t: CGAffineTransform) -> CGSize { + return applying(t) + } + + /** + Retrieves the size based on a given CATransform3D. + - Parameter _ t: A CGAffineTransform. + - Returns: A CGSize. + */ + func transform(_ t: CATransform3D) -> CGSize { + return applying(CATransform3DGetAffineTransform(t)) + } +} + +extension CGRect { + /// A center point based on the origin and size values. + var center: CGPoint { + return CGPoint(x: origin.x + size.width / 2, y: origin.y + size.height / 2) + } + + /// The bounding box size based from from the frame's rect. + var bounds: CGRect { + return CGRect(origin: .zero, size: size) + } + + /** + An initializer with a given point and size. + - Parameter center: A CGPoint. + - Parameter size: A CGSize. + */ + init(center: CGPoint, size: CGSize) { + self.init(x: center.x - size.width / 2, y: center.y - size.height / 2, width: size.width, height: size.height) + } +} + +extension CGFloat { + /** + Calculates the limiting position to an area. + - Parameter _ a: A CGFloat. + - Parameter _ b: A CGFloat. + - Returns: A CGFloat. + */ + func clamp(_ a: CGFloat, _ b: CGFloat) -> CGFloat { + return self < a ? a : self > b ? b : self + } +} + +extension CGPoint { + /** + Calculates a translation point based on the origin value. + - Parameter _ dx: A CGFloat. + - Parameter _ dy: A CGFloat. + - Returns: A CGPoint. + */ + func translate(_ dx: CGFloat, dy: CGFloat) -> CGPoint { + return CGPoint(x: x + dx, y: y + dy) + } + + /** + Calculates a transform point based on a given CGAffineTransform. + - Parameter _ t: CGAffineTransform. + - Returns: A CGPoint. + */ + func transform(_ t: CGAffineTransform) -> CGPoint { + return applying(t) + } + + /** + Calculates a transform point based on a given CATransform3D. + - Parameter _ t: CATransform3D. + - Returns: A CGPoint. + */ + func transform(_ t: CATransform3D) -> CGPoint { + return applying(CATransform3DGetAffineTransform(t)) + } + + /** + Calculates the distance between the CGPoint and given CGPoint. + - Parameter _ b: A CGPoint. + - Returns: A CGFloat. + */ + func distance(_ b: CGPoint) -> CGFloat { + return sqrt(pow(x - b.x, 2) + pow(y - b.y, 2)) + } +} + +/** + A handler for the (+) operator. + - Parameter left: A CGPoint. + - Parameter right: A CGPoint. + - Returns: A CGPoint. + */ +func +(left: CGPoint, right: CGPoint) -> CGPoint { + return CGPoint(x: left.x + right.x, y: left.y + right.y) +} + +/** + A handler for the (-) operator. + - Parameter left: A CGPoint. + - Parameter right: A CGPoint. + - Returns: A CGPoint. + */ +func -(left: CGPoint, right: CGPoint) -> CGPoint { + return CGPoint(x: left.x - right.x, y: left.y - right.y) +} + +/** + A handler for the (/) operator. + - Parameter left: A CGPoint. + - Parameter right: A CGFloat. + - Returns: A CGPoint. + */ +func /(left: CGPoint, right: CGFloat) -> CGPoint { + return CGPoint(x: left.x / right, y: left.y / right) +} + +/** + A handler for the (/) operator. + - Parameter left: A CGPoint. + - Parameter right: A CGPoint. + - Returns: A CGPoint. + */ +func /(left: CGPoint, right: CGPoint) -> CGPoint { + return CGPoint(x: left.x / right.x, y: left.y / right.y) +} + +/** + A handler for the (/) operator. + - Parameter left: A CGSize. + - Parameter right: A CGSize. + - Returns: A CGSize. + */ +func /(left: CGSize, right: CGSize) -> CGSize { + return CGSize(width: left.width / right.width, height: left.height / right.height) +} + +/** + A handler for the (*) operator. + - Parameter left: A CGPoint. + - Parameter right: A CGFloat. + - Returns: A CGPoint. + */ +func *(left: CGPoint, right: CGFloat) -> CGPoint { + return CGPoint(x: left.x * right, y: left.y * right) +} + +/** + A handler for the (*) operator. + - Parameter left: A CGPoint. + - Parameter right: A CGSize. + - Returns: A CGPoint. + */ +func *(left: CGPoint, right: CGSize) -> CGPoint { + return CGPoint(x: left.x * right.width, y: left.y * right.width) +} + +/** + A handler for the (*) operator. + - Parameter left: A CGFloat. + - Parameter right: A CGPoint. + - Returns: A CGPoint. + */ +func *(left: CGFloat, right: CGPoint) -> CGPoint { + return right * left +} + +/** + A handler for the (*) operator. + - Parameter left: A CGPoint. + - Parameter right: A CGPoint. + - Returns: A CGPoint. + */ +func *(left: CGPoint, right: CGPoint) -> CGPoint { + return CGPoint(x: left.x * right.x, y: left.y * right.y) +} + +/** + A handler for the (*) prefix. + - Parameter left: A CGSize. + - Parameter right: A CGFloat. + - Returns: A CGSize. + */ +func *(left: CGSize, right: CGFloat) -> CGSize { + return CGSize(width: left.width * right, height: left.height * right) +} + +/** + A handler for the (*) prefix. + - Parameter left: A CGSize. + - Parameter right: A CGSize. + - Returns: A CGSize. + */ +func *(left: CGSize, right: CGSize) -> CGSize { + return CGSize(width: left.width * right.width, height: left.height * right.width) +} + +/** + A handler for the (==) operator. + - Parameter lhs: A CATransform3D. + - Parameter rhs: A CATransform3D. + - Returns: A Bool. + */ +func ==(lhs: CATransform3D, rhs: CATransform3D) -> Bool { + var lhs = lhs + var rhs = rhs + return memcmp(&lhs, &rhs, MemoryLayout.size) == 0 +} + +/** + A handler for the (!=) operator. + - Parameter lhs: A CATransform3D. + - Parameter rhs: A CATransform3D. + - Returns: A Bool. + */ +func !=(lhs: CATransform3D, rhs: CATransform3D) -> Bool { + return !(lhs == rhs) +} + +/** + A handler for the (-) prefix. + - Parameter point: A CGPoint. + - Returns: A CGPoint. + */ +prefix func -(point: CGPoint) -> CGPoint { + return CGPoint.zero - point +} + +/** + A handler for the (abs) function. + - Parameter _ p: A CGPoint. + - Returns: A CGPoint. + */ +func abs(_ p: CGPoint) -> CGPoint { + return CGPoint(x: abs(p.x), y: abs(p.y)) +} diff --git a/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Extensions/Motion+Obj-C.swift b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Extensions/Motion+Obj-C.swift new file mode 100644 index 0000000..cf2f032 --- /dev/null +++ b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Extensions/Motion+Obj-C.swift @@ -0,0 +1,54 @@ +/* + * The MIT License (MIT) + * + * Copyright (C) 2017, Daniel Dahan and CosmicMind, Inc. . + * 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. + */ + +internal struct AssociatedObject { + /** + Gets the Obj-C reference for the instance object within the UIView extension. + - Parameter base: Base object. + - Parameter key: Memory key pointer. + - Parameter initializer: Object initializer. + - Returns: The associated reference for the initializer object. + */ + static func get(base: Any, key: UnsafePointer, initializer: () -> T) -> T { + if let v = objc_getAssociatedObject(base, key) as? T { + return v + } + + let v = initializer() + objc_setAssociatedObject(base, key, v, .OBJC_ASSOCIATION_RETAIN) + return v + } + + /** + Sets the Obj-C reference for the instance object within the UIView extension. + - Parameter base: Base object. + - Parameter key: Memory key pointer. + - Parameter value: The object instance to set for the associated object. + - Returns: The associated reference for the initializer object. + */ + static func set(base: Any, key: UnsafePointer, value: T) { + objc_setAssociatedObject(base, key, value, .OBJC_ASSOCIATION_RETAIN) + } +} diff --git a/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Extensions/Motion+UIKit.swift b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Extensions/Motion+UIKit.swift new file mode 100644 index 0000000..41fd9bb --- /dev/null +++ b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Extensions/Motion+UIKit.swift @@ -0,0 +1,58 @@ +/* + * The MIT License (MIT) + * + * Copyright (C) 2017, Daniel Dahan and CosmicMind, Inc. . + * All rights reserved. + * + * Original Inspiration & Author + * Copyright (c) 2016 Luke Zhao + * + * 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 UIKit + +fileprivate let parameterRegex = "(?:\\-?\\d+(\\.?\\d+)?)|\\w+" +fileprivate let transitionsRegex = "(\\w+)(?:\\(([^\\)]*)\\))?" + +internal extension NSObject { + /// Copies an object using NSKeyedArchiver. + func copyWithArchiver() -> Any? { + return NSKeyedUnarchiver.unarchiveObject(with: NSKeyedArchiver.archivedData(withRootObject: self))! + } +} + +internal extension UIColor { + /// A tuple of the rgba components. + var components: (r: CGFloat, g: CGFloat, b: CGFloat, a: CGFloat) { + var r: CGFloat = 0 + var g: CGFloat = 0 + var b: CGFloat = 0 + var a: CGFloat = 0 + + getRed(&r, green: &g, blue: &b, alpha: &a) + + return (r, g, b, a) + } + + /// The alpha component value. + var alphaComponent: CGFloat { + return components.a + } +} diff --git a/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Extensions/Motion+UIView.swift b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Extensions/Motion+UIView.swift new file mode 100644 index 0000000..f0af6c7 --- /dev/null +++ b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Extensions/Motion+UIView.swift @@ -0,0 +1,257 @@ +/* + * The MIT License (MIT) + * + * Copyright (C) 2017, Daniel Dahan and CosmicMind, Inc. . + * All rights reserved. + * + * Original Inspiration & Author + * Copyright (c) 2016 Luke Zhao + * + * 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 UIKit + +fileprivate var AssociatedInstanceKey: UInt8 = 0 + +fileprivate struct AssociatedInstance { + /// A boolean indicating whether Motion is enabled. + fileprivate var isEnabled: Bool + + /// An optional reference to the motion identifier. + fileprivate var identifier: String? + + /// An optional reference to the motion animations. + fileprivate var animations: [MotionAnimation]? + + /// An optional reference to the motion transition animations. + fileprivate var transitions: [MotionTransition]? + + /// An alpha value. + fileprivate var alpha: CGFloat? +} + +fileprivate extension UIView { + /// AssociatedInstance reference. + fileprivate var associatedInstance: AssociatedInstance { + get { + return AssociatedObject.get(base: self, key: &AssociatedInstanceKey) { + return AssociatedInstance(isEnabled: true, identifier: nil, animations: nil, transitions: nil, alpha: 1) + } + } + set(value) { + AssociatedObject.set(base: self, key: &AssociatedInstanceKey, value: value) + } + } +} + +public extension UIView { + /// A boolean that indicates whether motion is enabled. + @IBInspectable + var isMotionEnabled: Bool { + get { + return associatedInstance.isEnabled + } + set(value) { + associatedInstance.isEnabled = value + } + } + + /// An identifier value used to connect views across UIViewControllers. + @IBInspectable + var motionIdentifier: String? { + get { + return associatedInstance.identifier + } + set(value) { + associatedInstance.identifier = value + } + } + + /** + A function that accepts CAAnimation objects and executes them on the + view's backing layer. + - Parameter animations: A list of CAAnimations. + */ + func animate(_ animations: CAAnimation...) { + layer.animate(animations) + } + + /** + A function that accepts an Array of CAAnimation objects and executes + them on the view's backing layer. + - Parameter animations: An Array of CAAnimations. + */ + func animate(_ animations: [CAAnimation]) { + layer.animate(animations) + } + + /** + A function that accepts a list of MotionAnimation values and executes + them on the view's backing layer. + - Parameter animations: A list of MotionAnimation values. + */ + func animate(_ animations: MotionAnimation...) { + layer.animate(animations) + } + + /** + A function that accepts an Array of MotionAnimation values and executes + them on the view's backing layer. + - Parameter animations: An Array of MotionAnimation values. + - Parameter completion: An optional completion block. + */ + func animate(_ animations: [MotionAnimation], completion: (() -> Void)? = nil) { + layer.animate(animations, completion: completion) + } + + /** + A function that accepts a list of MotionTransition values. + - Parameter transitions: A list of MotionTransition values. + */ + func transition(_ transitions: MotionTransition...) { + transition(transitions) + } + + /** + A function that accepts an Array of MotionTransition values. + - Parameter transitions: An Array of MotionTransition values. + */ + func transition(_ transitions: [MotionTransition]) { + motionTransitions = transitions + } +} + +internal extension UIView { + /// The animations to run while in transition. + var motionTransitions: [MotionTransition]? { + get { + return associatedInstance.transitions + } + set(value) { + associatedInstance.transitions = value + } + } + + /// The animations to run while in transition. + var motionAlpha: CGFloat? { + get { + return associatedInstance.alpha + } + set(value) { + associatedInstance.alpha = value + } + } + + /// Computes the rotate of the view. + var motionRotationAngle: CGFloat { + get { + return CGFloat(atan2f(Float(transform.b), Float(transform.a))) * 180 / CGFloat(Double.pi) + } + set(value) { + transform = CGAffineTransform(rotationAngle: CGFloat(Double.pi) * value / 180) + } + } + + /// The global position of a view. + var motionPosition: CGPoint { + return superview?.convert(layer.position, to: nil) ?? layer.position + } + + /// The layer.transform of a view. + var motionTransform: CATransform3D { + get { + return layer.transform + } + set(value) { + layer.transform = value + } + } + + /// Computes the scale X axis value of the view. + var motionScaleX: CGFloat { + return transform.a + } + + /// Computes the scale Y axis value of the view. + var motionScaleY: CGFloat { + return transform.b + } +} + +internal extension UIView { + /// Retrieves a single Array of UIViews that are in the view hierarchy. + var flattenedViewHierarchy: [UIView] { + guard isMotionEnabled else { + return [] + } + + if #available(iOS 9.0, *) { + return isHidden && (superview is UICollectionView || superview is UIStackView || self is UITableViewCell) ? [] : ([self] + subviews.flatMap { $0.flattenedViewHierarchy }) + } + + return isHidden && (superview is UICollectionView || self is UITableViewCell) ? [] : ([self] + subviews.flatMap { $0.flattenedViewHierarchy }) + } + + /** + Retrieves the optimized duration based on the given parameters. + - Parameter fromPosition: A CGPoint. + - Parameter toPosition: An optional CGPoint. + - Parameter size: An optional CGSize. + - Parameter transform: An optional CATransform3D. + - Returns: A TimeInterval. + */ + func optimizedDuration(fromPosition: CGPoint, toPosition: CGPoint?, size: CGSize?, transform: CATransform3D?) -> TimeInterval { + let toPos = toPosition ?? fromPosition + let fromSize = (layer.presentation() ?? layer).bounds.size + let toSize = size ?? fromSize + let fromTransform = (layer.presentation() ?? layer).transform + let toTransform = transform ?? fromTransform + + let realFromPos = CGPoint.zero.transform(fromTransform) + fromPosition + let realToPos = CGPoint.zero.transform(toTransform) + toPos + + let realFromSize = fromSize.transform(fromTransform) + let realToSize = toSize.transform(toTransform) + + let movePoints = realFromPos.distance(realToPos) + realFromSize.bottomRight.distance(realToSize.bottomRight) + + // duration is 0.2 @ 0 to 0.375 @ 500 + return 0.208 + Double(movePoints.clamp(0, 500)) / 3000 + } + + /** + Takes a snapshot of a view usinag the UI graphics context. + - Returns: A UIView with an embedded UIImageView. + */ + func slowSnapshotView() -> UIView { + UIGraphicsBeginImageContextWithOptions(bounds.size, isOpaque, 0) + layer.render(in: UIGraphicsGetCurrentContext()!) + + let image = UIGraphicsGetImageFromCurrentImageContext() + UIGraphicsEndImageContext() + + let imageView = UIImageView(image: image) + imageView.frame = bounds + + let snapshotView = UIView(frame: bounds) + snapshotView.addSubview(imageView) + return snapshotView + } +} diff --git a/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Extensions/Motion+UIViewController.swift b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Extensions/Motion+UIViewController.swift new file mode 100644 index 0000000..087e79a --- /dev/null +++ b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Extensions/Motion+UIViewController.swift @@ -0,0 +1,326 @@ +/* + * The MIT License (MIT) + * + * Copyright (C) 2017, Daniel Dahan and CosmicMind, Inc. . + * All rights reserved. + * + * Original Inspiration & Author + * Copyright (c) 2016 Luke Zhao + * + * 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 UIKit + +fileprivate var AssociatedInstanceKey: UInt8 = 0 + +fileprivate struct AssociatedInstance { + /// A reference to the modal animation. + var modalTransitionType: MotionTransitionType + + /// A reference to the navigation animation. + var navigationTransitionType: MotionTransitionType + + /// A reference to the tabBar animation. + var tabBarTransitionType: MotionTransitionType + + /// A reference to the stored snapshot. + var storedSnapshot: UIView? + + /** + A reference to the previous navigation controller delegate + before Motion was enabled. + */ + var previousNavigationDelegate: UINavigationControllerDelegate? + + /** + A reference to the previous tab bar controller delegate + before Motion was enabled. + */ + var previousTabBarDelegate: UITabBarControllerDelegate? +} + +extension UIViewController { + /// AssociatedInstance reference. + fileprivate var associatedInstance: AssociatedInstance { + get { + return AssociatedObject.get(base: self, key: &AssociatedInstanceKey) { + return AssociatedInstance(modalTransitionType: .auto, + navigationTransitionType: .auto, + tabBarTransitionType: .auto, + storedSnapshot: nil, + previousNavigationDelegate: nil, + previousTabBarDelegate: nil) + } + } + set(value) { + AssociatedObject.set(base: self, key: &AssociatedInstanceKey, value: value) + } + } + + /// default motion animation type for presenting & dismissing modally + public var motionModalTransitionType: MotionTransitionType { + get { + return associatedInstance.modalTransitionType + } + set(value) { + associatedInstance.modalTransitionType = value + } + } + + /// used for .overFullScreen presentation + internal var motionStoredSnapshot: UIView? { + get { + return associatedInstance.storedSnapshot + } + set(value) { + associatedInstance.storedSnapshot = value + } + } + + /** + A reference to the previous navigation controller delegate + before Motion was enabled. + */ + internal var previousNavigationDelegate: UINavigationControllerDelegate? { + get { + return associatedInstance.previousNavigationDelegate + } + set(value) { + associatedInstance.previousNavigationDelegate = value + } + } + + /** + A reference to the previous tab bar controller delegate + before Motion was enabled. + */ + internal var previousTabBarDelegate: UITabBarControllerDelegate? { + get { + return associatedInstance.previousTabBarDelegate + } + set(value) { + associatedInstance.previousTabBarDelegate = value + } + } + + ///A boolean that indicates whether Motion is enabled or disabled. + @IBInspectable + public var isMotionEnabled: Bool { + get { + return transitioningDelegate is Motion + } + set(value) { + guard value != isMotionEnabled else { + return + } + + if value { + transitioningDelegate = Motion.shared + + if let v = self as? UINavigationController { + previousNavigationDelegate = v.delegate + v.delegate = Motion.shared + } + + if let v = self as? UITabBarController { + previousTabBarDelegate = v.delegate + v.delegate = Motion.shared + } + } else { + transitioningDelegate = nil + + if let v = self as? UINavigationController, v.delegate is Motion { + v.delegate = previousNavigationDelegate + } + + if let v = self as? UITabBarController, v.delegate is Motion { + v.delegate = previousTabBarDelegate + } + } + } + } +} + +extension UINavigationController { + /// Default motion animation type for push and pop within the navigation controller. + public var motionNavigationTransitionType: MotionTransitionType { + get { + return associatedInstance.navigationTransitionType + } + set(value) { + associatedInstance.navigationTransitionType = value + } + } +} + +extension UITabBarController { + /// Default motion animation type for switching tabs within the tab bar controller. + public var motionTabBarTransitionType: MotionTransitionType { + get { + return associatedInstance.tabBarTransitionType + } + set(value) { + associatedInstance.tabBarTransitionType = value + } + } +} + +extension UIViewController { + /** + Dismiss the current view controller with animation. Will perform a + navigationController.popViewController if the current view controller + is contained inside a navigationController + */ + @IBAction + public func motionDismissViewController() { + if let v = navigationController, self != v.viewControllers.first { + v.popViewController(animated: true) + } else { + dismiss(animated: true) + } + } + + /// Unwind to the root view controller using Motion. + @IBAction + public func motionUnwindToRootViewController() { + motionUnwindToViewController { $0.presentingViewController == nil } + } + + /// Unwind to a specific view controller using Motion. + public func motionUnwindToViewController(_ toViewController: UIViewController) { + motionUnwindToViewController { $0 == toViewController } + } + + /// Unwind to a view controller that responds to the given selector using Motion. + public func motionUnwindToViewController(withSelector: Selector) { + motionUnwindToViewController { $0.responds(to: withSelector) } + } + + /// Unwind to a view controller with given class using Motion + public func motionUnwindToViewController(withClass: AnyClass) { + motionUnwindToViewController { $0.isKind(of: withClass) } + } + + /// Unwind to a view controller that the matchBlock returns true on. + public func motionUnwindToViewController(withMatchBlock: (UIViewController) -> Bool) { + var target: UIViewController? + var current: UIViewController? = self + + while nil == target && nil != current { + if let childViewControllers = (current as? UINavigationController)?.childViewControllers ?? current!.navigationController?.childViewControllers { + for v in childViewControllers.reversed() { + if self != v, withMatchBlock(v) { + target = v + break + } + } + } + + guard nil == target else { + continue + } + + current = current?.presentingViewController + + guard let v = current, withMatchBlock(v) else { + continue + } + + target = v + } + + guard let v = target else { + return + } + + guard nil != v.presentedViewController else { + v.navigationController?.popToViewController(v, animated: true) + return + } + + v.navigationController?.popToViewController(v, animated: false) + + let fromVC = navigationController ?? self + let toVC = v.navigationController ?? v + + if v.presentedViewController != fromVC { + /** + UIKit's UIViewController.dismiss will jump to target.presentedViewController then perform the dismiss. + We overcome this behavior by inserting a snapshot into target.presentedViewController + And also force Motion to use the current view controller as the fromViewController. + */ + Motion.shared.fromViewController = fromVC + + guard let snapshot = fromVC.view.snapshotView(afterScreenUpdates: true) else { + return + } + + toVC.presentedViewController?.view.addSubview(snapshot) + } + + toVC.dismiss(animated: true) + } + + /** + Replace the current view controller with another view controller within the + navigation/modal stack. + - Parameter with next: A UIViewController. + */ + public func motionReplaceViewController(with next: UIViewController) { + guard !Motion.shared.isTransitioning else { + print("motionReplaceViewController cancelled because Motion was doing a transition. Use Motion.shared.cancel(animated: false) or Motion.shared.end(animated: false) to stop the transition first before calling motionReplaceViewController.") + return + } + + if let nc = navigationController { + var v = nc.childViewControllers + + if !v.isEmpty { + v.removeLast() + v.append(next) + } + + if nc.isMotionEnabled { + Motion.shared.forceNonInteractive = true + } + + nc.setViewControllers(v, animated: true) + } else if let container = view.superview { + let presentingVC = presentingViewController + + Motion.shared.transition(from: self, to: next, in: container) { [weak self] (isFinished) in + guard isFinished else { + return + } + + UIApplication.shared.keyWindow?.addSubview(next.view) + + guard let pvc = presentingVC else { + UIApplication.shared.keyWindow?.rootViewController = next + return + } + + self?.dismiss(animated: false) { + pvc.present(next, animated: false) + } + } + } + } +} diff --git a/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Extensions/MotionAnimationFillMode.swift b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Extensions/MotionAnimationFillMode.swift new file mode 100644 index 0000000..220fa5b --- /dev/null +++ b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Extensions/MotionAnimationFillMode.swift @@ -0,0 +1,51 @@ +/* + * The MIT License (MIT) + * + * Copyright (C) 2017, Daniel Dahan and CosmicMind, Inc. . + * 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 UIKit + +@objc(MotionAnimationFillMode) +public enum MotionAnimationFillMode: Int { + case forwards + case backwards + case both + case removed +} + +/** + Converts the MotionAnimationFillMode enum value to a corresponding String. + - Parameter mode: An MotionAnimationFillMode enum value. + */ +public func MotionAnimationFillModeToValue(mode: MotionAnimationFillMode) -> String { + switch mode { + case .forwards: + return kCAFillModeForwards + case .backwards: + return kCAFillModeBackwards + case .both: + return kCAFillModeBoth + case .removed: + return kCAFillModeRemoved + } +} diff --git a/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Motion.swift b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Motion.swift new file mode 100644 index 0000000..0ea1ab1 --- /dev/null +++ b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Motion.swift @@ -0,0 +1,853 @@ +/* + * The MIT License (MIT) + * + * Copyright (C) 2017, Daniel Dahan and CosmicMind, Inc. . + * All rights reserved. + * + * Original Inspiration & Author + * Copyright (c) 2016 Luke Zhao + * + * 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 UIKit + +@objc(MotionViewControllerDelegate) +public protocol MotionViewControllerDelegate { + /** + An optional delegation method that is executed motion will start the transition. + - Parameter motion: A Motion instance. + - Parameter willStartTransitionFrom viewController: A UIViewController. + */ + @objc + optional func motionWillStartTransition(motion: Motion) + + /** + An optional delegation method that is executed motion did end the transition. + - Parameter motion: A Motion instance. + - Parameter willStartTransitionFrom viewController: A UIViewController. + */ + @objc + optional func motionDidEndTransition(motion: Motion) + + /** + An optional delegation method that is executed motion did cancel the transition. + - Parameter motion: A Motion instance. + - Parameter willStartTransitionFrom viewController: A UIViewController. + */ + @objc + optional func motionDidCancelTransition(motion: Motion) + + /** + An optional delegation method that is executed when the source + view controller will start the transition. + - Parameter motion: A Motion instance. + - Parameter willStartTransitionFrom viewController: A UIViewController. + */ + @objc + optional func motion(motion: Motion, willStartTransitionFrom viewController: UIViewController) + + /** + An optional delegation method that is executed when the source + view controller did end the transition. + - Parameter motion: A Motion instance. + - Parameter willStartTransitionFrom viewController: A UIViewController. + */ + @objc + optional func motion(motion: Motion, didEndTransitionFrom viewController: UIViewController) + + /** + An optional delegation method that is executed when the source + view controller did cancel the transition. + - Parameter motion: A Motion instance. + - Parameter willStartTransitionFrom viewController: A UIViewController. + */ + @objc + optional func motion(motion: Motion, didCancelTransitionFrom viewController: UIViewController) + + /** + An optional delegation method that is executed when the destination + view controller will start the transition. + - Parameter motion: A Motion instance. + - Parameter willStartTransitionFrom viewController: A UIViewController. + */ + @objc + optional func motion(motion: Motion, willStartTransitionTo viewController: UIViewController) + + /** + An optional delegation method that is executed when the destination + view controller did end the transition. + - Parameter motion: A Motion instance. + - Parameter willStartTransitionFrom viewController: A UIViewController. + */ + @objc + optional func motion(motion: Motion, didEndTransitionTo viewController: UIViewController) + + /** + An optional delegation method that is executed when the destination + view controller did cancel the transition. + - Parameter motion: A Motion instance. + - Parameter willStartTransitionFrom viewController: A UIViewController. + */ + @objc + optional func motion(motion: Motion, didCancelTransitionTo viewController: UIViewController) +} + +/** + ### The singleton class/object for controlling interactive transitions. + + ```swift + Motion.shared + ``` + + #### Use the following methods for controlling the interactive transition: + + ```swift + func update(progress:Double) + func end() + func cancel() + func apply(transitions: [MotionTransition], to view: UIView) + ``` + */ +public class Motion: MotionController { + /// Shared singleton object for controlling the transition + public static let shared = Motion() + + /// Source view controller. + public internal(set) var fromViewController: UIViewController? + + /// Destination view controller. + public internal(set) var toViewController: UIViewController? + + /// Whether or not we are presenting the destination view controller. + public internal(set) var isPresenting = true + + /// Progress of the current transition, 0 if a transition is not happening. + public override var elapsedTime: TimeInterval { + didSet { + guard isTransitioning else { + return + } + + transitionContext?.updateInteractiveTransition(CGFloat(elapsedTime)) + } + } + + /// Indicates whether the transition is animating or not. + public var isAnimating = false + + /** + A UIViewControllerContextTransitioning object provided by UIKit, which + might be nil when isTransitioning. This happens when calling motionReplaceViewController + */ + internal weak var transitionContext: UIViewControllerContextTransitioning? + + /// A reference to a fullscreen snapshot. + internal var fullScreenSnapshot: UIView! + + /// Default animation type. + internal var defaultAnimation = MotionTransitionType.auto + + /// The color of the transitioning container. + internal var containerBackgroundColor: UIColor? + + /** + By default, Motion will always appear to be interactive to UIKit. This forces it to appear non-interactive. + Used when doing a motionReplaceViewController within a UINavigationController, to fix a bug with + UINavigationController.setViewControllers not able to handle interactive transitions. + */ + internal var forceNonInteractive = false + + /// Inserts the toViews first. + internal var insertToViewFirst = false + + /// Indicates whether a UINavigationController is transitioning. + internal var isNavigationController = false + + /// Indicates whether a UITabBarController is transitioning. + internal var isTabBarController = false + + /// Indicates whether a UINavigationController or UITabBarController is transitioning. + internal var isContainerController: Bool { + return isNavigationController || isTabBarController + } + + /// Indicates whether the from view controller is full screen. + internal var fromOverFullScreen: Bool { + guard let v = fromViewController else { + return false + } + + return !isContainerController && (.overFullScreen == v.modalPresentationStyle || .overCurrentContext == v.modalPresentationStyle) + } + + /// Indicates whether the to view controller is full screen. + internal var toOverFullScreen: Bool { + guard let v = toViewController else { + return false + } + + return !isContainerController && (.overFullScreen == v.modalPresentationStyle || .overCurrentContext == v.modalPresentationStyle) + } + + /// A reference to the fromView, fromViewController.view. + internal var fromView: UIView? { + return fromViewController?.view + } + + /// A reference to the toView, toViewController.view. + internal var toView: UIView? { + return toViewController?.view + } + + /// An initializer. + internal override init() { + super.init() + } +} + +public extension Motion { + /// Turn off built-in animations for the next transition. + func disableDefaultAnimationForNextTransition() { + defaultAnimation = .none + } + + /** + Set the default animation for the next transition. This may override the + root-view's motionTransitions during the transition. + - Parameter animation: A MotionTransitionType. + */ + func setAnimationForNextTransition(_ animation: MotionTransitionType) { + defaultAnimation = animation + } + + /** + Set the container background color for the next transition. + - Parameter _ color: An optional UIColor. + */ + func setContainerBackgroundColorForNextTransition(_ color: UIColor?) { + containerBackgroundColor = color + } +} + +fileprivate extension Motion { + /// Starts the transition animation. + func start() { + guard isTransitioning else { + return + } + + prepareViewControllers() + prepareSnapshotView() + prepareTransition() + prepareContext() + prepareToView() + prepareViewHierarchy() + processContext() + prepareTransitionPairs() + processForAnimation() + } +} + +internal extension Motion { + override func animate() { + guard let tv = toView else { + return + } + + context.unhide(view: tv) + + updateContainerBackgroundColor() + updateInsertOrder() + + super.animate() + + fullScreenSnapshot?.removeFromSuperview() + } + + override func complete(isFinished: Bool) { + guard isTransitioning else { + return + } + + guard let c = container else { + return + } + + guard let tc = transitionContainer else { + return + } + + guard let fv = fromView else { + return + } + + guard let tv = toView else { + return + } + + context.clean() + + if isFinished && isPresenting && toOverFullScreen { + // finished presenting a overFullScreen view controller. + context.unhide(rootView: tv) + context.removeSnapshots(rootView: tv) + context.storeViewAlpha(rootView: fv) + + fromViewController!.motionStoredSnapshot = container + fv.removeFromSuperview() + fv.addSubview(c) + } else if !isFinished && !isPresenting && fromOverFullScreen { + // Cancelled dismissing a overFullScreen view controller. + context.unhide(rootView: fv) + context.removeSnapshots(rootView: fv) + context.storeViewAlpha(rootView: tv) + + toViewController!.motionStoredSnapshot = container + tv.removeFromSuperview() + tv.addSubview(c) + } else { + context.unhideAll() + context.removeAllSnapshots() + c.removeFromSuperview() + } + + // Move fromView & toView back from our container back to the one supplied by UIKit. + if (toOverFullScreen && isFinished) || (fromOverFullScreen && !isFinished) { + tc.addSubview(isFinished ? fv : tv) + } + + tc.addSubview(isFinished ? tv : fv) + + if isPresenting != isFinished, !isContainerController { + // Only happens when present a .overFullScreen view controller. + // bug: http://openradar.appspot.com/radar?id=5320103646199808 + UIApplication.shared.keyWindow!.addSubview(isPresenting ? fv : tv) + } + + // use temp variables to remember these values + // because we have to reset everything before calling + // any delegate or completion block + let tContext = transitionContext + let fvc = fromViewController + let tvc = toViewController + + resetTransition() + + super.complete(isFinished: isFinished) + + if isFinished { + processEndTransitionDelegation(transitionContext: tContext, fromViewController: fvc, toViewController: tvc) + } else { + processCancelTransitionDelegation(transitionContext: tContext, fromViewController: fvc, toViewController: tvc) + } + + tContext?.completeTransition(isFinished) + } +} + +fileprivate extension Motion { + /// Resets the transition values. + func resetTransition() { + transitionContext = nil + fromViewController = nil + toViewController = nil + containerBackgroundColor = nil + isNavigationController = false + isTabBarController = false + forceNonInteractive = false + insertToViewFirst = false + defaultAnimation = .auto + } +} + +fileprivate extension Motion { + /// Prepares the from and to view controllers. + func prepareViewControllers() { + processStartTransitionDelegation(fromViewController: fromViewController, toViewController: toViewController) + } + + /// Prepares the snapshot view, which hides any flashing that may occur. + func prepareSnapshotView() { + guard let v = transitionContainer else { + return + } + + fullScreenSnapshot = v.window?.snapshotView(afterScreenUpdates: true) ?? fromView?.snapshotView(afterScreenUpdates: true) + (v.window ?? transitionContainer)?.addSubview(fullScreenSnapshot) + + if let v = fromViewController?.motionStoredSnapshot { + v.removeFromSuperview() + fromViewController?.motionStoredSnapshot = nil + } + + if let v = toViewController?.motionStoredSnapshot { + v.removeFromSuperview() + toViewController?.motionStoredSnapshot = nil + } + } + + /// Prepares the MotionContext instance. + func prepareContext() { + guard let v = container else { + return + } + + guard let fv = fromView else { + return + } + + guard let tv = toView else { + return + } + + context.loadViewAlpha(rootView: tv) + v.addSubview(tv) + + context.loadViewAlpha(rootView: fv) + v.addSubview(fv) + } + + /// Prepares the toView instance. + func prepareToView() { + guard let fv = fromView else { + return + } + + guard let tv = toView else { + return + } + + tv.frame = fv.frame + tv.updateConstraints() + tv.setNeedsLayout() + tv.layoutIfNeeded() + } + + /// Prepares the view hierarchy. + func prepareViewHierarchy() { + guard let fv = fromView else { + return + } + + guard let tv = toView else { + return + } + + context.set(fromViews: fv.flattenedViewHierarchy, toViews: tv.flattenedViewHierarchy) + } +} + +internal extension Motion { + override func prepareTransition() { + super.prepareTransition() + insert(preprocessor: TransitionPreprocessor(motion: self), before: DurationPreprocessor.self) + } + + override func prepareTransitionPairs() { + super.prepareTransitionPairs() + + guard let tv = toView else { + return + } + + context.hide(view: tv) + } +} + +fileprivate extension Motion { + /// Processes the animations. + func processForAnimation() { + #if os(tvOS) + animate() + #else + if isNavigationController { + // When animating within navigationController, we have to dispatch later into the main queue. + // otherwise snapshots will be pure white. Possibly a bug with UIKit + DispatchQueue.main.async { [weak self] in + self?.animate() + } + } else { + animate() + } + #endif + } + + /** + Processes the start transition delegation methods. + - Parameter fromViewController: An optional UIViewController. + - Parameter toViewController: An optional UIViewController. + */ + func processStartTransitionDelegation(fromViewController: UIViewController?, toViewController: UIViewController?) { + guard let fvc = fromViewController else { + return + } + + guard let tvc = toViewController else { + return + } + + processForMotionDelegate(viewController: fvc) { [weak self] in + guard let s = self else { + return + } + + $0.motion?(motion: s, willStartTransitionTo: tvc) + $0.motionWillStartTransition?(motion: s) + } + + processForMotionDelegate(viewController: tvc) { [weak self] in + guard let s = self else { + return + } + + $0.motion?(motion: s, willStartTransitionFrom: fvc) + $0.motionWillStartTransition?(motion: s) + } + } + + /** + Processes the end transition delegation methods. + - Parameter transitionContext: An optional UIViewControllerContextTransitioning. + - Parameter fromViewController: An optional UIViewController. + - Parameter toViewController: An optional UIViewController. + */ + func processEndTransitionDelegation(transitionContext: UIViewControllerContextTransitioning?, fromViewController: UIViewController?, toViewController: UIViewController?) { + guard let fvc = fromViewController else { + return + } + + guard let tvc = toViewController else { + return + } + + processForMotionDelegate(viewController: fvc) { [weak self] in + guard let s = self else { + return + } + + $0.motion?(motion: s, didEndTransitionTo: tvc) + $0.motionDidEndTransition?(motion: s) + } + + processForMotionDelegate(viewController: tvc) { [weak self] in + guard let s = self else { + return + } + + $0.motion?(motion: s, didEndTransitionFrom: fvc) + $0.motionDidEndTransition?(motion: s) + } + + transitionContext?.finishInteractiveTransition() + } + + /** + Processes the cancel transition delegation methods. + - Parameter transitionContext: An optional UIViewControllerContextTransitioning. + - Parameter fromViewController: An optional UIViewController. + - Parameter toViewController: An optional UIViewController. + */ + func processCancelTransitionDelegation(transitionContext: UIViewControllerContextTransitioning?, fromViewController: UIViewController?, toViewController: UIViewController?) { + guard let fvc = fromViewController else { + return + } + + guard let tvc = toViewController else { + return + } + + processForMotionDelegate(viewController: fvc) { [weak self] in + guard let s = self else { + return + } + + $0.motion?(motion: s, didCancelTransitionTo: tvc) + $0.motionDidCancelTransition?(motion: s) + } + + processForMotionDelegate(viewController: tvc) { [weak self] in + guard let s = self else { + return + } + + $0.motion?(motion: s, didCancelTransitionFrom: fvc) + $0.motionDidCancelTransition?(motion: s) + } + + transitionContext?.finishInteractiveTransition() + } +} + +fileprivate extension Motion { + /// Updates the container background color. + func updateContainerBackgroundColor() { + if let v = containerBackgroundColor { + container?.backgroundColor = v + } else if !toOverFullScreen && !fromOverFullScreen { + container?.backgroundColor = toView?.backgroundColor + } + } + + /// Updates the insertToViewFirst boolean for animators. + func updateInsertOrder() { + if fromOverFullScreen { + insertToViewFirst = true + } + + for v in animators { + (v as? MotionHasInsertOrder)?.insertToViewFirst = insertToViewFirst + } + } +} + +internal extension Motion { + /** + A helper transition function. + - Parameter from: A UIViewController. + - Parameter to: A UIViewController. + - Parameter in view: A UIView. + - Parameter completion: An optional completion handler. + */ + func transition(from: UIViewController, to: UIViewController, in view: UIView, completion: ((Bool) -> Void)? = nil) { + guard !isTransitioning else { + return + } + + isPresenting = true + transitionContainer = view + fromViewController = from + toViewController = to + completionCallback = completion + + start() + } +} + +internal extension Motion { + /** + Helper for processing the MotionViewControllerDelegate. + - Parameter viewController: A UIViewController of type `T`. + - Parameter execute: A callback for execution during processing. + */ + func processForMotionDelegate(viewController: T, execute: (MotionViewControllerDelegate) -> Void) { + if let delegate = viewController as? MotionViewControllerDelegate { + execute(delegate) + } + + if let v = viewController as? UINavigationController, + let delegate = v.topViewController as? MotionViewControllerDelegate { + execute(delegate) + } + + if let v = viewController as? UITabBarController, + let delegate = v.viewControllers?[v.selectedIndex] as? MotionViewControllerDelegate { + execute(delegate) + } + } +} + +extension Motion: UIViewControllerAnimatedTransitioning { + /** + The animation method that is used to coordinate the transition. + - Parameter using transitionContext: A UIViewControllerContextTransitioning. + */ + public func animateTransition(using context: UIViewControllerContextTransitioning) { + guard !isTransitioning else { + return + } + + transitionContext = context + fromViewController = fromViewController ?? context.viewController(forKey: .from) + toViewController = toViewController ?? context.viewController(forKey: .to) + transitionContainer = context.containerView + + start() + } + + /** + Returns the transition duration time interval. + - Parameter using transitionContext: An optional UIViewControllerContextTransitioning. + - Returns: A TimeInterval that is the total animation time including delays. + */ + public func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { + return 0 // Will be updated dynamically. + } + + public func animationEnded(_ transitionCompleted: Bool) { + isAnimating = !transitionCompleted + } +} + +extension Motion: UIViewControllerTransitioningDelegate { + /// A reference to the interactive transitioning instance. + var interactiveTransitioning: UIViewControllerInteractiveTransitioning? { + return forceNonInteractive ? nil : self + } + + public func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? { + self.isPresenting = true + self.fromViewController = fromViewController ?? presenting + self.toViewController = toViewController ?? presented + return self + } + + public func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { + self.isPresenting = false + self.fromViewController = fromViewController ?? dismissed + return self + } + + public func interactionControllerForDismissal(using animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? { + return interactiveTransitioning + } + + public func interactionControllerForPresentation(using animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? { + return interactiveTransitioning + } +} + +extension Motion: UIViewControllerInteractiveTransitioning { + public var wantsInteractiveStart: Bool { + return true + } + public func startInteractiveTransition(_ transitionContext: UIViewControllerContextTransitioning) { + animateTransition(using: transitionContext) + } +} + +extension Motion: UINavigationControllerDelegate { + public func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationControllerOperation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? { + self.isPresenting = .push == operation + self.fromViewController = fromViewController ?? fromVC + self.toViewController = toViewController ?? toVC + self.isNavigationController = true + return self + } + + public func navigationController(_ navigationController: UINavigationController, interactionControllerFor animationController: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? { + return interactiveTransitioning + } +} + +extension Motion: UITabBarControllerDelegate { + public func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool { + return !isAnimating + } + + public func tabBarController(_ tabBarController: UITabBarController, interactionControllerFor animationController: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? { + return interactiveTransitioning + } + + public func tabBarController(_ tabBarController: UITabBarController, animationControllerForTransitionFrom fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? { + isAnimating = true + + let fromVCIndex = tabBarController.childViewControllers.index(of: fromVC)! + let toVCIndex = tabBarController.childViewControllers.index(of: toVC)! + + self.isPresenting = toVCIndex > fromVCIndex + self.fromViewController = fromViewController ?? fromVC + self.toViewController = toViewController ?? toVC + self.isTabBarController = true + + return self + } +} + +public typealias MotionDelayCancelBlock = (Bool) -> Void + +extension Motion { + /** + Executes a block of code after a time delay. + - Parameter duration: An animation duration time. + - Parameter animations: An animation block. + - Parameter execute block: A completion block that is executed once + the animations have completed. + */ + @discardableResult + public class func delay(_ time: TimeInterval, execute: @escaping () -> Void) -> MotionDelayCancelBlock? { + var cancelable: MotionDelayCancelBlock? + + let delayed: MotionDelayCancelBlock = { + if !$0 { + DispatchQueue.main.async(execute: execute) + } + + cancelable = nil + } + + cancelable = delayed + + DispatchQueue.main.asyncAfter(deadline: .now() + time) { + cancelable?(false) + } + + return cancelable + } + + /** + Cancels the delayed MotionDelayCancelBlock. + - Parameter delayed completion: An MotionDelayCancelBlock. + */ + public class func cancel(delayed completion: MotionDelayCancelBlock) { + completion(true) + } + + /** + Disables the default animations set on CALayers. + - Parameter animations: A callback that wraps the animations to disable. + */ + public class func disable(_ animations: (() -> Void)) { + animate(duration: 0, animations: animations) + } + + /** + Runs an animation with a specified duration. + - Parameter duration: An animation duration time. + - Parameter animations: An animation block. + - Parameter timingFunction: A CAMediaTimingFunction. + - Parameter completion: A completion block that is executed once + the animations have completed. + */ + public class func animate(duration: CFTimeInterval, timingFunction: CAMediaTimingFunction = .easeInOut, animations: (() -> Void), completion: (() -> Void)? = nil) { + CATransaction.begin() + CATransaction.setAnimationDuration(duration) + CATransaction.setCompletionBlock(completion) + CATransaction.setAnimationTimingFunction(timingFunction) + animations() + CATransaction.commit() + } + + /** + Creates a CAAnimationGroup. + - Parameter animations: An Array of CAAnimation objects. + - Parameter timingFunction: A CAMediaTimingFunction. + - Parameter duration: An animation duration time for the group. + - Returns: A CAAnimationGroup. + */ + public class func animate(group animations: [CAAnimation], timingFunction: CAMediaTimingFunction = .easeInOut, duration: CFTimeInterval = 0.5) -> CAAnimationGroup { + let group = CAAnimationGroup() + group.fillMode = MotionAnimationFillModeToValue(mode: .both) + group.isRemovedOnCompletion = false + group.animations = animations + group.duration = duration + group.timingFunction = timingFunction + return group + } +} diff --git a/Example/Pods/Material/Sources/Frameworks/Motion/Sources/MotionAnimation.swift b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/MotionAnimation.swift new file mode 100644 index 0000000..2b0b3d8 --- /dev/null +++ b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/MotionAnimation.swift @@ -0,0 +1,404 @@ +/* + * The MIT License (MIT) + * + * Copyright (C) 2017, Daniel Dahan and CosmicMind, Inc. . + * All rights reserved. + * + * Original Inspiration & Author + * Copyright (c) 2016 Luke Zhao + * + * 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 UIKit + +public class MotionAnimation { + /// A reference to the callback that applies the MotionAnimationState. + internal let apply: (inout MotionAnimationState) -> Void + + /** + An initializer that accepts a given callback. + - Parameter applyFunction: A given callback. + */ + init(applyFunction: @escaping (inout MotionAnimationState) -> Void) { + apply = applyFunction + } +} + +public extension MotionAnimation { + /** + Animates a view's current background color to the + given color. + - Parameter color: A UIColor. + - Returns: A MotionAnimation. + */ + static func background(color: UIColor) -> MotionAnimation { + return MotionAnimation { + $0.backgroundColor = color.cgColor + } + } + + /** + Animates a view's current border color to the + given color. + - Parameter color: A UIColor. + - Returns: A MotionAnimation. + */ + static func border(color: UIColor) -> MotionAnimation { + return MotionAnimation { + $0.borderColor = color.cgColor + } + } + + /** + Animates a view's current border width to the + given width. + - Parameter width: A CGFloat. + - Returns: A MotionAnimation. + */ + static func border(width: CGFloat) -> MotionAnimation { + return MotionAnimation { + $0.borderWidth = width + } + } + + /** + Animates a view's current corner radius to the + given radius. + - Parameter radius: A CGFloat. + - Returns: A MotionAnimation. + */ + static func corner(radius: CGFloat) -> MotionAnimation { + return MotionAnimation { + $0.cornerRadius = radius + } + } + + /** + Animates a view's current transform (perspective, scale, rotate) + to the given one. + - Parameter _ transform: A CATransform3D. + - Returns: A MotionAnimation. + */ + static func transform(_ transform: CATransform3D) -> MotionAnimation { + return MotionAnimation { + $0.transform = transform + } + } + + /** + Animates a view's current rotation to the given x, y, + and z values. + - Parameter x: A CGFloat. + - Parameter y: A CGFloat. + - Parameter z: A CGFloat. + - Returns: A MotionAnimation. + */ + static func rotate(x: CGFloat = 0, y: CGFloat = 0, z: CGFloat = 0) -> MotionAnimation { + return MotionAnimation { + var t = $0.transform ?? CATransform3DIdentity + t = CATransform3DRotate(t, CGFloat(Double.pi) * x / 180, 1, 0, 0) + t = CATransform3DRotate(t, CGFloat(Double.pi) * y / 180, 0, 1, 0) + $0.transform = CATransform3DRotate(t, CGFloat(Double.pi) * z / 180, 0, 0, 1) + } + } + + /** + Animates a view's current rotation to the given point. + - Parameter _ point: A CGPoint. + - Parameter z: A CGFloat. + - Returns: A MotionAnimation. + */ + static func rotate(_ point: CGPoint, z: CGFloat = 0) -> MotionAnimation { + return .rotate(x: point.x, y: point.y, z: z) + } + + /** + Rotate 2d. + - Parameter _ z: A CGFloat. + - Returns: A MotionAnimation. + */ + static func rotate(_ z: CGFloat) -> MotionAnimation { + return .rotate(z: z) + } + + /** + Animates a view's current spin to the given x, y, + and z values. + - Parameter x: A CGFloat. + - Parameter y: A CGFloat. + - Parameter z: A CGFloat. + - Returns: A MotionAnimation. + */ + static func spin(x: CGFloat = 0, y: CGFloat = 0, z: CGFloat = 0) -> MotionAnimation { + return MotionAnimation { + $0.spin = (x, y, z) + } + } + + /** + Animates a view's current spin to the given point. + - Parameter _ point: A CGPoint. + - Parameter z: A CGFloat. + - Returns: A MotionAnimation. + */ + static func spin(_ point: CGPoint, z: CGFloat = 0) -> MotionAnimation { + return .spin(x: point.x, y: point.y, z: z) + } + + /** + Spin 2d. + - Parameter _ z: A CGFloat. + - Returns: A MotionAnimation. + */ + static func spin(_ z: CGFloat) -> MotionAnimation { + return .spin(z: z) + } + + /** + Animates the view's current scale to the given x, y, and z scale values. + - Parameter x: A CGFloat. + - Parameter y: A CGFloat. + - Parameter z: A CGFloat. + - Returns: A MotionAnimation. + */ + static func scale(x: CGFloat = 1, y: CGFloat = 1, z: CGFloat = 1) -> MotionAnimation { + return MotionAnimation { + $0.transform = CATransform3DScale($0.transform ?? CATransform3DIdentity, x, y, z) + } + } + + /** + Animates the view's current x & y scale to the given scale value. + - Parameter _ xy: A CGFloat. + - Returns: A MotionAnimation. + */ + static func scale(_ xy: CGFloat) -> MotionAnimation { + return .scale(x: xy, y: xy) + } + + /** + Animates a view equal to the distance given by the x, y, and z values. + - Parameter x: A CGFloat. + - Parameter y: A CGFloat. + - Parameter z: A CGFloat. + - Returns: A MotionAnimation. + */ + static func translate(x: CGFloat = 0, y: CGFloat = 0, z: CGFloat = 0) -> MotionAnimation { + return MotionAnimation { + $0.transform = CATransform3DTranslate($0.transform ?? CATransform3DIdentity, x, y, z) + } + } + + /** + Animates a view equal to the distance given by a point and z value. + - Parameter _ point: A CGPoint. + - Parameter z: A CGFloat. + - Returns: A MotionAnimation. + */ + static func translate(_ point: CGPoint, z: CGFloat = 0) -> MotionAnimation { + return .translate(x: point.x, y: point.y, z: z) + } + + /** + Animates a view's current position to the given point. + - Parameter _ point: A CGPoint. + - Returns: A MotionAnimation. + */ + static func position(_ point: CGPoint) -> MotionAnimation { + return MotionAnimation { + $0.position = point + } + } + + /// Fades the view in during an animation. + static var fadeIn = MotionAnimation.fade(1) + + /// Fades the view out during an animation. + static var fadeOut = MotionAnimation.fade(0) + + /** + Animates a view's current opacity to the given one. + - Parameter _ opacity: A Double. + - Returns: A MotionAnimation. + */ + static func fade(_ opacity: Double) -> MotionAnimation { + return MotionAnimation { + $0.opacity = opacity + } + } + + /** + Animates a view's current zPosition to the given position. + - Parameter _ position: An Int. + - Returns: A MotionAnimation. + */ + static func zPosition(_ position: CGFloat) -> MotionAnimation { + return MotionAnimation { + $0.zPosition = position + } + } + + /** + Animates a view's current size to the given one. + - Parameter _ size: A CGSize. + - Returns: A MotionAnimation. + */ + static func size(_ size: CGSize) -> MotionAnimation { + return MotionAnimation { + $0.size = size + } + } + + /** + Animates a view's current shadow path to the given one. + - Parameter path: A CGPath. + - Returns: A MotionAnimation. + */ + static func shadow(path: CGPath) -> MotionAnimation { + return MotionAnimation { + $0.shadowPath = path + } + } + + /** + Animates a view's current shadow color to the given one. + - Parameter color: A UIColor. + - Returns: A MotionAnimation. + */ + static func shadow(color: UIColor) -> MotionAnimation { + return MotionAnimation { + $0.shadowColor = color.cgColor + } + } + + /** + Animates a view's current shadow offset to the given one. + - Parameter offset: A CGSize. + - Returns: A MotionAnimation. + */ + static func shadow(offset: CGSize) -> MotionAnimation { + return MotionAnimation { + $0.shadowOffset = offset + } + } + + /** + Animates a view's current shadow opacity to the given one. + - Parameter opacity: A Float. + - Returns: A MotionAnimation. + */ + static func shadow(opacity: Float) -> MotionAnimation { + return MotionAnimation { + $0.shadowOpacity = opacity + } + } + + /** + Animates a view's current shadow radius to the given one. + - Parameter radius: A CGFloat. + - Returns: A MotionAnimation. + */ + static func shadow(radius: CGFloat) -> MotionAnimation { + return MotionAnimation { + $0.shadowRadius = radius + } + } + + /** + Animates the views shadow offset, opacity, and radius. + - Parameter offset: A CGSize. + - Parameter opacity: A Float. + - Parameter radius: A CGFloat. + */ + static func depth(offset: CGSize, opacity: Float, radius: CGFloat) -> MotionAnimation { + return MotionAnimation { + $0.shadowOffset = offset + $0.shadowOpacity = opacity + $0.shadowRadius = radius + } + } + + /** + Animates the views shadow offset, opacity, and radius. + - Parameter _ depth: A tuple (CGSize, FLoat, CGFloat). + */ + static func depth(_ depth: (CGSize, Float, CGFloat)) -> MotionAnimation { + return .depth(offset: depth.0, opacity: depth.1, radius: depth.2) + } + + /** + Available in iOS 9+, animates a view using the spring API, + given a stiffness and damping. + - Parameter stiffness: A CGFlloat. + - Parameter damping: A CGFloat. + - Returns: A MotionAnimation. + */ + @available(iOS 9, *) + static func spring(stiffness: CGFloat, damping: CGFloat) -> MotionAnimation { + return MotionAnimation { + $0.spring = (stiffness, damping) + } + } + + /** + The duration of the view's animation. If a duration of 0 is used, + the value will be converted to 0.01, to give a close to zero value. + - Parameter _ duration: A TimeInterval. + - Returns: A MotionAnimation. + */ + static func duration(_ duration: TimeInterval) -> MotionAnimation { + return MotionAnimation { + $0.duration = duration + } + } + + /** + Delays the animation of a given view. + - Parameter _ time: TimeInterval. + - Returns: A MotionAnimation. + */ + static func delay(_ time: TimeInterval) -> MotionAnimation { + return MotionAnimation { + $0.delay = time + } + } + + /** + Sets the view's timing function for the animation. + - Parameter _ timingFunction: A CAMediaTimingFunction. + - Returns: A MotionAnimation. + */ + static func timingFunction(_ timingFunction: CAMediaTimingFunction) -> MotionAnimation { + return MotionAnimation { + $0.timingFunction = timingFunction + } + } + + /** + Creates a completion block handler that is executed once the animation + is done. + - Parameter _ execute: A callback to execute once completed. + */ + static func completion(_ execute: @escaping () -> Void) -> MotionAnimation { + return MotionAnimation { + $0.completion = execute + } + } +} diff --git a/Example/Pods/Material/Sources/Frameworks/Motion/Sources/MotionAnimationState.swift b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/MotionAnimationState.swift new file mode 100644 index 0000000..6f7b8ca --- /dev/null +++ b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/MotionAnimationState.swift @@ -0,0 +1,150 @@ +/* + * The MIT License (MIT) + * + * Copyright (C) 2017, Daniel Dahan and CosmicMind, Inc. . + * All rights reserved. + * + * Original Inspiration & Author + * Copyright (c) 2016 Luke Zhao + * + * 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 UIKit + +public struct MotionAnimationState { + /// A reference to the position. + public var position: CGPoint? + + /// A reference to the size. + public var size: CGSize? + + /// A reference to the transform. + public var transform: CATransform3D? + + /// A reference to the spin tuple. + public var spin: (x: CGFloat, y: CGFloat, z: CGFloat)? + + /// A reference to the opacity. + public var opacity: Double? + + /// A reference to the cornerRadius. + public var cornerRadius: CGFloat? + + /// A reference to the backgroundColor. + public var backgroundColor: CGColor? + + /// A reference to the zPosition. + public var zPosition: CGFloat? + + /// A reference to the borderWidth. + public var borderWidth: CGFloat? + + /// A reference to the borderColor. + public var borderColor: CGColor? + + /// A reference to the shadowColor. + public var shadowColor: CGColor? + + /// A reference to the shadowOpacity. + public var shadowOpacity: Float? + + /// A reference to the shadowOffset. + public var shadowOffset: CGSize? + + /// A reference to the shadowRadius. + public var shadowRadius: CGFloat? + + /// A reference to the shadowPath. + public var shadowPath: CGPath? + + /// A reference to the spring animation settings. + public var spring: (CGFloat, CGFloat)? + + /// A time delay on starting the animation. + public var delay: TimeInterval = 0 + + /// The duration of the animation. + public var duration: TimeInterval = 0.35 + + /// The timing function value of the animation. + public var timingFunction = CAMediaTimingFunction.easeInOut + + /// Custom target states. + public var custom: [String: Any]? + + /// Completion block. + public var completion: (() -> Void)? + + /** + An initializer that accepts an Array of MotionAnimations. + - Parameter animations: An Array of MotionAnimations. + */ + init(animations: [MotionAnimation]) { + append(contentsOf: animations) + } +} + +extension MotionAnimationState { + /** + Adds a MotionAnimation to the current state. + - Parameter _ element: A MotionAnimation. + */ + public mutating func append(_ element: MotionAnimation) { + element.apply(&self) + } + + /** + Adds an Array of MotionAnimations to the current state. + - Parameter contentsOf elements: An Array of MotionAnimations. + */ + public mutating func append(contentsOf elements: [MotionAnimation]) { + for v in elements { + v.apply(&self) + } + } + + /** + A subscript that returns a custom value for a specified key. + - Parameter key: A String. + - Returns: An optional Any value. + */ + public subscript(key: String) -> Any? { + get { + return custom?[key] + } + set(value) { + if nil == custom { + custom = [:] + } + + custom![key] = value + } + } +} + +extension MotionAnimationState: ExpressibleByArrayLiteral { + /** + An initializer implementing the ExpressibleByArrayLiteral protocol. + - Parameter arrayLiteral elements: A list of MotionAnimations. + */ + public init(arrayLiteral elements: MotionAnimation...) { + append(contentsOf: elements) + } +} diff --git a/Example/Pods/Material/Sources/Frameworks/Motion/Sources/MotionCAAnimation.swift b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/MotionCAAnimation.swift new file mode 100644 index 0000000..8b13d1a --- /dev/null +++ b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/MotionCAAnimation.swift @@ -0,0 +1,317 @@ +/* + * The MIT License (MIT) + * + * Copyright (C) 2017, Daniel Dahan and CosmicMind, Inc. . + * 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 UIKit + +public enum MotionAnimationKeyPath: String { + case backgroundColor + case borderColor + case borderWidth + case cornerRadius + case transform + case rotate = "transform.rotation" + case rotateX = "transform.rotation.x" + case rotateY = "transform.rotation.y" + case rotateZ = "transform.rotation.z" + case scale = "transform.scale" + case scaleX = "transform.scale.x" + case scaleY = "transform.scale.y" + case scaleZ = "transform.scale.z" + case translation = "transform.translation" + case translationX = "transform.translation.x" + case translationY = "transform.translation.y" + case translationZ = "transform.translation.z" + case position + case opacity + case zPosition + case width = "bounds.size.width" + case height = "bounds.size.height" + case size = "bounds.size" + case shadowPath + case shadowColor + case shadowOffset + case shadowOpacity + case shadowRadius +} + +extension CABasicAnimation { + /** + A convenience initializer that takes a given MotionAnimationKeyPath. + - Parameter keyPath: An MotionAnimationKeyPath. + */ + public convenience init(keyPath: MotionAnimationKeyPath) { + self.init(keyPath: keyPath.rawValue) + } +} + +public struct MotionCAAnimation {} + +fileprivate extension MotionCAAnimation { + /** + Creates a CABasicAnimation. + - Parameter keyPath: A MotionAnimationKeyPath. + - Parameter toValue: An Any value that is the end state of the animation. + */ + static func createAnimation(keyPath: MotionAnimationKeyPath, toValue: Any) -> CABasicAnimation { + let a = CABasicAnimation(keyPath: keyPath) + a.toValue = toValue + return a + } +} + +@available(iOS 9.0, *) +internal extension MotionCAAnimation { + /** + Converts a CABasicAnimation to a CASpringAnimation. + - Parameter animation: A CABasicAnimation. + - Parameter stiffness: A CGFloat. + - Parameter damping: A CGFloat. + */ + static func convert(animation: CABasicAnimation, stiffness: CGFloat, damping: CGFloat) -> CASpringAnimation { + let a = CASpringAnimation(keyPath: animation.keyPath) + a.fromValue = animation.fromValue + a.toValue = animation.toValue + a.stiffness = stiffness + a.damping = damping + return a + } +} + +public extension MotionCAAnimation { + /** + Creates a CABasicAnimation for the backgroundColor key path. + - Parameter color: A UIColor. + - Returns: A CABasicAnimation. + */ + static func background(color: UIColor) -> CABasicAnimation { + return MotionCAAnimation.createAnimation(keyPath: .backgroundColor, toValue: color.cgColor) + } + + /** + Creates a CABasicAnimation for the borderColor key path. + - Parameter color: A UIColor. + - Returns: A CABasicAnimation. + */ + static func border(color: UIColor) -> CABasicAnimation { + return MotionCAAnimation.createAnimation(keyPath: .borderColor, toValue: color.cgColor) + } + + /** + Creates a CABasicAnimation for the borderWidth key path. + - Parameter width: A CGFloat. + - Returns: A CABasicAnimation. + */ + static func border(width: CGFloat) -> CABasicAnimation { + return MotionCAAnimation.createAnimation(keyPath: .borderWidth, toValue: NSNumber(floatLiteral: Double(width))) + } + + /** + Creates a CABasicAnimation for the cornerRadius key path. + - Parameter radius: A CGFloat. + - Returns: A CABasicAnimation. + */ + static func corner(radius: CGFloat) -> CABasicAnimation { + return MotionCAAnimation.createAnimation(keyPath: .cornerRadius, toValue: NSNumber(floatLiteral: Double(radius))) + } + + /** + Creates a CABasicAnimation for the transform key path. + - Parameter _ t: A CATransform3D object. + - Returns: A CABasicAnimation. + */ + static func transform(_ t: CATransform3D) -> CABasicAnimation { + return MotionCAAnimation.createAnimation(keyPath: .transform, toValue: NSValue(caTransform3D: t)) + } + + /** + Creates a CABasicAnimation for the transform.scale key path. + - Parameter xyz: A CGFloat. + - Returns: A CABasicAnimation. + */ + public static func scale(_ xyz: CGFloat) -> CABasicAnimation { + let a = CABasicAnimation(keyPath: .scale) + a.toValue = NSNumber(value: Double(xyz)) + return a + } + + /** + Creates a CABasicAnimation for the transform.scale.x key path. + - Parameter x: A CGFloat. + - Returns: A CABasicAnimation. + */ + public static func scale(x: CGFloat) -> CABasicAnimation { + let a = CABasicAnimation(keyPath: .scaleX) + a.toValue = NSNumber(value: Double(x)) + return a + } + + /** + Creates a CABasicAnimation for the transform.scale.y key path. + - Parameter y: A CGFloat. + - Returns: A CABasicAnimation. + */ + public static func scale(y: CGFloat) -> CABasicAnimation { + let a = CABasicAnimation(keyPath: .scaleY) + a.toValue = NSNumber(value: Double(y)) + return a + } + + /** + Creates a CABasicAnimation for the transform.scale.z key path. + - Parameter z: A CGFloat. + - Returns: A CABasicAnimation. + */ + public static func scale(z: CGFloat) -> CABasicAnimation { + let a = CABasicAnimation(keyPath: .scaleZ) + a.toValue = NSNumber(value: Double(z)) + return a + } + + /** + Creates a CABasicAnimation for the transform.rotate.x key path. + - Parameter x: An optional CGFloat. + - Returns: A CABasicAnimation. + */ + static func spin(x: CGFloat) -> CABasicAnimation { + return MotionCAAnimation.createAnimation(keyPath: .rotateX, toValue: NSNumber(value: Double(CGFloat(Double.pi) * 2 * x))) + } + + /** + Creates a CABasicAnimation for the transform.rotate.y key path. + - Parameter y: An optional CGFloat. + - Returns: A CABasicAnimation. + */ + static func spin(y: CGFloat) -> CABasicAnimation { + return MotionCAAnimation.createAnimation(keyPath: .rotateY, toValue: NSNumber(value: Double(CGFloat(Double.pi) * 2 * y))) + } + + /** + Creates a CABasicAnimation for the transform.rotate.z key path. + - Parameter z: An optional CGFloat. + - Returns: A CABasicAnimation. + */ + static func spin(z: CGFloat) -> CABasicAnimation { + return MotionCAAnimation.createAnimation(keyPath: .rotateZ, toValue: NSNumber(value: Double(CGFloat(Double.pi) * 2 * z))) + } + + /** + Creates a CABasicAnimation for the position key path. + - Parameter _ point: A CGPoint. + - Returns: A CABasicAnimation. + */ + static func position(_ point: CGPoint) -> CABasicAnimation { + return MotionCAAnimation.createAnimation(keyPath: .position, toValue: NSValue(cgPoint: point)) + } + + /** + Creates a CABasicAnimation for the opacity key path. + - Parameter _ opacity: A Double. + - Returns: A CABasicAnimation. + */ + static func fade(_ opacity: Double) -> CABasicAnimation { + return MotionCAAnimation.createAnimation(keyPath: .opacity, toValue: NSNumber(floatLiteral: opacity)) + } + + /** + Creates a CABasicaAnimation for the zPosition key path. + - Parameter _ position: A CGFloat. + - Returns: A CABasicAnimation. + */ + static func zPosition(_ position: CGFloat) -> CABasicAnimation { + return MotionCAAnimation.createAnimation(keyPath: .zPosition, toValue: NSNumber(value: Double(position))) + } + + /** + Creates a CABasicaAnimation for the width key path. + - Parameter width: A CGFloat. + - Returns: A CABasicAnimation. + */ + static func width(_ width: CGFloat) -> CABasicAnimation { + return MotionCAAnimation.createAnimation(keyPath: .width, toValue: NSNumber(floatLiteral: Double(width))) + } + + /** + Creates a CABasicaAnimation for the height key path. + - Parameter height: A CGFloat. + - Returns: A CABasicAnimation. + */ + static func height(_ height: CGFloat) -> CABasicAnimation { + return MotionCAAnimation.createAnimation(keyPath: .height, toValue: NSNumber(floatLiteral: Double(height))) + } + + /** + Creates a CABasicaAnimation for the height key path. + - Parameter size: A CGSize. + - Returns: A CABasicAnimation. + */ + static func size(_ size: CGSize) -> CABasicAnimation { + return MotionCAAnimation.createAnimation(keyPath: .size, toValue: NSValue(cgSize: size)) + } + + /** + Creates a CABasicAnimation for the shadowPath key path. + - Parameter path: A CGPath. + - Returns: A CABasicAnimation. + */ + static func shadow(path: CGPath) -> CABasicAnimation { + return MotionCAAnimation.createAnimation(keyPath: .shadowPath, toValue: path) + } + + /** + Creates a CABasicAnimation for the shadowColor key path. + - Parameter color: A UIColor. + - Returns: A CABasicAnimation. + */ + static func shadow(color: UIColor) -> CABasicAnimation { + return MotionCAAnimation.createAnimation(keyPath: .shadowColor, toValue: color.cgColor) + } + + /** + Creates a CABasicAnimation for the shadowOffset key path. + - Parameter offset: A CGSize. + - Returns: A CABasicAnimation. + */ + static func shadow(offset: CGSize) -> CABasicAnimation { + return MotionCAAnimation.createAnimation(keyPath: .shadowOffset, toValue: NSValue(cgSize: offset)) + } + + /** + Creates a CABasicAnimation for the shadowOpacity key path. + - Parameter opacity: A Float. + - Returns: A CABasicAnimation. + */ + static func shadow(opacity: Float) -> CABasicAnimation { + return MotionCAAnimation.createAnimation(keyPath: .shadowOpacity, toValue: NSNumber(floatLiteral: Double(opacity))) + } + + /** + Creates a CABasicAnimation for the shadowRadius key path. + - Parameter radius: A CGFloat. + - Returns: A CABasicAnimation. + */ + static func shadow(radius: CGFloat) -> CABasicAnimation { + return MotionCAAnimation.createAnimation(keyPath: .shadowRadius, toValue: NSNumber(floatLiteral: Double(radius))) + } +} diff --git a/Example/Pods/Material/Sources/Frameworks/Motion/Sources/MotionContext.swift b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/MotionContext.swift new file mode 100644 index 0000000..ae4903c --- /dev/null +++ b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/MotionContext.swift @@ -0,0 +1,486 @@ +/* + * The MIT License (MIT) + * + * Copyright (C) 2017, Daniel Dahan and CosmicMind, Inc. . + * All rights reserved. + * + * Original Inspiration & Author + * Copyright (c) 2016 Luke Zhao + * + * 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 UIKit + +public class MotionContext { + /// A reference of motion identifiers to source views. + internal var motionIdentifierToSourceView = [String: UIView]() + + /// A reference of motion identifiers to destination views. + internal var motionIdentifierToDestinationView = [String: UIView]() + + /// A reference of the snapshot to source/destination view. + internal var viewToSnapshot = [UIView: UIView]() + + /// A reference to the view to view alpha value. + internal var viewToAlphas = [UIView: CGFloat]() + + /// A reference of view to transition target state. + internal var viewToTargetState = [UIView: MotionTransitionState]() + + /// A reference of the superview to the subviews snapshots. + internal var superviewToNoSnapshotSubviewMap = [UIView: [(Int, UIView)]]() + + /// A reference to the default coordinate space for transitions. + internal var defaultCoordinateSpace = MotionCoordinateSpace.local + + /// The container view holding all of the animating views. + public let container: UIView + + /// A flattened list of all views from the source view controller. + public var fromViews: [UIView]! + + /// A flattened list of all views from the destination view controller. + public var toViews: [UIView]! + + /** + An initializer that accepts a container transition view. + - Parameter container: A UIView. + */ + internal init(container: UIView) { + self.container = container + } +} + +internal extension MotionContext { + /** + Sets the fromViews and toViews within the transition context. + - Parameter fromViews: An Array of UIViews. + - Parameter toViews: An Array of UIViews. + */ + func set(fromViews: [UIView], toViews: [UIView]) { + self.fromViews = fromViews + self.toViews = toViews + map(views: fromViews, identifierMap: &motionIdentifierToSourceView) + map(views: toViews, identifierMap: &motionIdentifierToDestinationView) + } + + /** + Maps the views to their respective identifier index. + - Parameter views: An Array of UIViews. + - Parameter identifierMap: A Dicionary of String to UIView pairs. + */ + func map(views: [UIView], identifierMap: inout [String: UIView]) { + for v in views { + v.layer.removeAllAnimations() + + if container.convert(v.bounds, from: v).intersects(container.bounds) { + if let i = v.motionIdentifier { + identifierMap[i] = v + } + + if let i = v.motionTransitions { + viewToTargetState[v] = MotionTransitionState(transitions: i) + } + } + } + } +} + +public extension MotionContext { + /** + A subscript that takes a given view and retrieves a + MotionTransitionState if one exists. + - Parameter view: A UIView. + - Returns: An optional MotionTransitionState. + */ + subscript(view: UIView) -> MotionTransitionState? { + get { + return viewToTargetState[view] + } + set { + viewToTargetState[view] = newValue + } + } +} + +public extension MotionContext { + /** + Retrieves a source view matching the motionIdentifier, nil if not found. + - Parameter for motionIdentifier: A String. + - Returns: An optional UIView. + */ + func sourceView(for motionIdentifier: String) -> UIView? { + return motionIdentifierToSourceView[motionIdentifier] + } + + /** + Retrieves a destination view matching the motionIdentifier, nil if not found. + - Parameter for motionIdentifier: A String. + - Returns: An optional UIView. + */ + func destinationView(for motionIdentifier: String) -> UIView? { + return motionIdentifierToDestinationView[motionIdentifier] + } + + /** + Retrieves the matching view with the same motionIdentifier found in the + source and destination view controllers. + - Returns: An optional UIView. + */ + func transitionPairedView(for view: UIView) -> UIView? { + if let i = view.motionIdentifier { + if view == sourceView(for: i) { + return destinationView(for: i) + + } else if view == destinationView(for: i) { + return sourceView(for: i) + } + } + + return nil + } + + /** + Retrieves the snapshot view for a given view. + - Parameter for view: A UIView. + - Returns: A UIView. + */ + func snapshotView(for view: UIView) -> UIView { + if let v = viewToSnapshot[view] { + return v + } + + var containerView = container + let coordinateSpace = viewToTargetState[view]?.coordinateSpace ?? defaultCoordinateSpace + + switch coordinateSpace { + case .local: + containerView = view + + while containerView != container, nil == viewToSnapshot[containerView], let superview = containerView.superview { + containerView = superview + } + + if let snapshot = viewToSnapshot[containerView] { + containerView = snapshot + } + case .sameParent: + containerView = view.superview! + + case .global: + break + } + + unhide(view: view) + + // Capture a snapshot without the alpha & cornerRadius values. + let oldCornerRadius = view.layer.cornerRadius + view.layer.cornerRadius = 0 + + let oldAlpha = view.alpha + view.alpha = 1 + + let snapshot: UIView + let snapshotType: MotionSnapshotType = self[view]?.snapshotType ?? .optimized + + switch snapshotType { + case .normal: + snapshot = view.snapshotView(afterScreenUpdates: true)! + + case .layerRender: + snapshot = view.slowSnapshotView() + + case .noSnapshot: + if nil == superviewToNoSnapshotSubviewMap[view.superview!] { + superviewToNoSnapshotSubviewMap[view.superview!] = [] + } + + superviewToNoSnapshotSubviewMap[view.superview!]!.append((view.superview!.subviews.index(of: view)!, view)) + snapshot = view + + case .optimized: + #if os(tvOS) + snapshot = view.snapshotView(afterScreenUpdates: true)! + + #else + if #available(iOS 9.0, *), let stackView = view as? UIStackView { + snapshot = stackView.slowSnapshotView() + + } else if let imageView = view as? UIImageView, view.subviews.isEmpty { + let contentView = UIImageView(image: imageView.image) + contentView.frame = imageView.bounds + contentView.contentMode = imageView.contentMode + contentView.tintColor = imageView.tintColor + contentView.backgroundColor = imageView.backgroundColor + + let snapShotView = UIView() + snapShotView.addSubview(contentView) + snapshot = snapShotView + + } else if let navigationBar = view as? UINavigationBar, navigationBar.isTranslucent { + let newNavigationBar = UINavigationBar(frame: navigationBar.frame) + newNavigationBar.barStyle = navigationBar.barStyle + newNavigationBar.tintColor = navigationBar.tintColor + newNavigationBar.barTintColor = navigationBar.barTintColor + newNavigationBar.clipsToBounds = false + + // Take a snapshot without the background. + navigationBar.layer.sublayers![0].opacity = 0 + let realSnapshot = navigationBar.snapshotView(afterScreenUpdates: true)! + navigationBar.layer.sublayers![0].opacity = 1 + + newNavigationBar.addSubview(realSnapshot) + snapshot = newNavigationBar + + } else if let effectView = view as? UIVisualEffectView { + snapshot = UIVisualEffectView(effect: effectView.effect) + snapshot.frame = effectView.bounds + + } else { + snapshot = view.snapshotView(afterScreenUpdates: true)! + } + #endif + } + + #if os(tvOS) + if let imageView = view as? UIImageView, imageView.adjustsImageWhenAncestorFocused { + snapshot.frame = imageView.focusedFrameGuide.layoutFrame + } + #endif + + view.layer.cornerRadius = oldCornerRadius + view.alpha = oldAlpha + + if .noSnapshot != snapshotType { + snapshot.layer.allowsGroupOpacity = false + + if !(view is UINavigationBar), let contentView = snapshot.subviews.get(0) { + /** + The snapshot's contentView must have the cornerRadius value, + since the snapshot might not have maskToBounds set + */ + contentView.layer.cornerRadius = view.layer.cornerRadius + contentView.layer.masksToBounds = true + } + + snapshot.layer.cornerRadius = view.layer.cornerRadius + snapshot.layer.zPosition = view.layer.zPosition + snapshot.layer.opacity = view.layer.opacity + snapshot.layer.isOpaque = view.layer.isOpaque + snapshot.layer.anchorPoint = view.layer.anchorPoint + snapshot.layer.masksToBounds = view.layer.masksToBounds + snapshot.layer.borderColor = view.layer.borderColor + snapshot.layer.borderWidth = view.layer.borderWidth + snapshot.layer.transform = view.layer.transform + snapshot.layer.contentsRect = view.layer.contentsRect + snapshot.layer.contentsScale = view.layer.contentsScale + + if self[view]?.displayShadow ?? true { + snapshot.layer.shadowRadius = view.layer.shadowRadius + snapshot.layer.shadowOpacity = view.layer.shadowOpacity + snapshot.layer.shadowColor = view.layer.shadowColor + snapshot.layer.shadowOffset = view.layer.shadowOffset + snapshot.layer.shadowPath = view.layer.shadowPath + } + } + + snapshot.frame = containerView.convert(view.bounds, from: view) + snapshot.motionIdentifier = view.motionIdentifier + + hide(view: view) + + if let pairedView = transitionPairedView(for: view), let pairedSnapshot = viewToSnapshot[pairedView] { + let siblingViews = pairedView.superview!.subviews + let nextSiblings = siblingViews[siblingViews.index(of: pairedView)!+1.. [UIView] { + var snapshots = [UIView]() + + for v in rootView.flattenedViewHierarchy { + if let snapshot = viewToSnapshot[v] { + snapshots.append(snapshot) + } + } + + return snapshots + } + + /** + Sets the alpha values for a given view and its subviews to the + stored alpha value. + - Parameter rootView: A UIView. + */ + func loadViewAlpha(rootView: UIView) { + if let storedAlpha = rootView.motionAlpha { + rootView.alpha = storedAlpha + rootView.motionAlpha = nil + } + + for subview in rootView.subviews { + loadViewAlpha(rootView: subview) + } + } + + /** + Stores the alpha values for a given view and its subviews. + - Parameter rootView: A UIView. + */ + func storeViewAlpha(rootView: UIView) { + rootView.motionAlpha = viewToAlphas[rootView] + + for subview in rootView.subviews { + storeViewAlpha(rootView: subview) + } + } +} diff --git a/Example/Pods/Material/Sources/Frameworks/Motion/Sources/MotionController.swift b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/MotionController.swift new file mode 100644 index 0000000..256e5d4 --- /dev/null +++ b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/MotionController.swift @@ -0,0 +1,563 @@ +/* + * The MIT License (MIT) + * + * Copyright (C) 2017, Daniel Dahan and CosmicMind, Inc. . + * All rights reserved. + * + * Original Inspiration & Author + * Copyright (c) 2016 Luke Zhao + * + * 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 UIKit + +public class MotionController: NSObject { + /// A reference to the MotionContext. + public internal(set) var context: MotionContext! + + /// A boolean indicating whether the transition interactive or not. + public var isInteractive: Bool { + return nil == displayLink + } + + /// Progress of the current transition. 0 if no transition is happening. + public internal(set) var elapsedTime: TimeInterval = 0 { + didSet { + guard isTransitioning else { + return + } + + updateTransitionObservers() + + guard isInteractive else { + updatePlugins() + return + } + + updateAnimators() + } + } + + /// A boolean indicating whether a transition is active. + public var isTransitioning: Bool { + return nil != transitionContainer + } + + /** + A view container used to hold all the animating views during a + transition. + */ + public internal(set) var container: UIView? + + /// UIKit's supplied transition container. + internal var transitionContainer: UIView? + + /// An optional completion callback. + internal var completionCallback: ((Bool) -> Void)? + + /// Binds the render cycle to the transition animation. + internal var displayLink: CADisplayLink? + + /// An Array of observers that are updated during a transition. + internal var transitionObservers: [MotionTransitionObserver]? + + /// Max duration used by MotionAnimators and MotionPlugins. + public internal(set) var totalDuration: TimeInterval = 0 + + /// The currently running animation duration. + internal var currentAnimationDuration: TimeInterval = 0 + + /// The start time of the animation. + internal var beginTime: TimeInterval? { + didSet { + guard nil != beginTime else { + displayLink?.isPaused = true + displayLink?.remove(from: RunLoop.main, forMode: RunLoopMode(rawValue: RunLoopMode.commonModes.rawValue)) + displayLink = nil + return + } + + guard nil == displayLink else { + return + } + + displayLink = CADisplayLink(target: self, selector: #selector(handleDisplayLink(_:))) + displayLink?.add(to: RunLoop.main, forMode: RunLoopMode(rawValue: RunLoopMode.commonModes.rawValue)) + } + } + + /// A boolean indicating if the transition has finished. + internal var isFinished = true + + /// An Array of MotionPreprocessors used during a transition. + internal fileprivate(set) lazy var preprocessors = [MotionPreprocessor]() + + /// An Array of MotionAnimators used during a transition. + internal fileprivate(set) lazy var animators = [MotionAnimator]() + + /// An Array of MotionPlugins used during a transition. + internal fileprivate(set) lazy var plugins = [MotionPlugin]() + + /// The matching fromViews to toViews based on the motionIdentifier value. + internal fileprivate(set) lazy var transitionPairs = [(fromViews: [UIView], toViews: [UIView])]() + + /// Plugins that are enabled during the transition. + internal static var enabledPlugins = [MotionPlugin.Type]() + + /// Initializer. + internal override init() {} +} + +public extension MotionController { + /** + Receive callbacks on each animation frame. + Observers will be cleaned when a transition completes. + - Parameter observer: A MotionTransitionObserver. + */ + func addTransitionObserver(observer: MotionTransitionObserver) { + if nil == transitionObservers { + transitionObservers = [] + } + + transitionObservers?.append(observer) + } +} + +fileprivate extension MotionController { + /// Updates the transition observers. + func updateTransitionObservers() { + guard let observers = transitionObservers else { + return + } + + for v in observers { + v.motion(transitionObserver: v, didUpdateWith: elapsedTime) + } + } + + /// Updates the animators. + func updateAnimators() { + let t = elapsedTime * totalDuration + for a in animators { + a.seek(to: t) + } + } + + /// Updates the plugins. + func updatePlugins() { + let t = elapsedTime * totalDuration + for p in plugins where p.requirePerFrameCallback { + p.seek(to: t) + } + } +} + +fileprivate extension MotionController { + /** + Handler for the DisplayLink updates. + - Parameter _ link: CADisplayLink. + */ + @objc + func handleDisplayLink(_ link: CADisplayLink) { + guard isTransitioning else { + return + } + + guard 0 < currentAnimationDuration else { + return + } + + guard let t = beginTime else { + return + } + + let cTime = CACurrentMediaTime() - t + + if cTime > currentAnimationDuration { + elapsedTime = isFinished ? 1 : 0 + + beginTime = nil + + complete(isFinished: isFinished) + + } else { + var eTime = cTime / totalDuration + + if !isFinished { + eTime = 1 - eTime + } + + elapsedTime = max(0, min(1, eTime)) + } + } +} + +public extension MotionController { + /** + Updates the elapsed time for the interactive transition. + - Parameter elapsedTime t: the current progress, must be between -1...1. + */ + public func update(elapsedTime t: TimeInterval) { + guard isTransitioning else { + return + } + + beginTime = nil + elapsedTime = max(-1, min(1, t)) + } + + /** + Finish the interactive transition. + Will stop the interactive transition and animate from the + current state to the **end** state + - Parameter isAnimated: A boolean indicating if the completion is animated. + */ + public func end(isAnimated: Bool = true) { + guard isTransitioning else { + return + } + + guard isAnimated else { + complete(isFinished: true) + return + } + + var t: TimeInterval = 0 + + for a in animators { + t = max(t, a.resume(at: elapsedTime * totalDuration, isReversed: false)) + } + + complete(after: t, isFinished: true) + } + + /** + Cancel the interactive transition. + Will stop the interactive transition and animate from the + current state to the **begining** state + - Parameter isAnimated: A boolean indicating if the completion is animated. + */ + public func cancel(isAnimated: Bool = true) { + guard isTransitioning else { + return + } + + guard isAnimated else { + complete(isFinished: false) + return + } + + var d: TimeInterval = 0 + + for a in animators { + var t = elapsedTime + if t < 0 { + t = -t + } + + d = max(d, a.resume(at: t * totalDuration, isReversed: true)) + } + + complete(after: d, isFinished: false) + } + + /** + Override transition animations during an interactive animation. + + For example: + + Motion.shared.apply([.position(x:50, y:50)], to: view) + + will set the view's position to 50, 50 + - Parameter transitions: An Array of MotionTransitions. + - Parameter to view: A UIView. + */ + public func apply(transitions: [MotionTransition], to view: UIView) { + guard isTransitioning else { + return + } + + let s = MotionTransitionState(transitions: transitions) + let v = context.transitionPairedView(for: view) ?? view + + for a in animators { + a.apply(state: s, to: v) + } + } +} + +internal extension MotionController { + /** + Load plugins, processors, animators, container, & context + The transitionContainer must already be set. + Subclasses should call context.set(fromViews: toViews) after + inserting fromViews & toViews into the container + */ + func prepareTransition() { + guard isTransitioning else { + return + } + + prepareTransitionContainer() + prepareContext() + preparePreprocessors() + prepareAnimators() + preparePlugins() + } + + /// Prepares the transition fromView & toView pairs. + func prepareTransitionPairs() { + guard isTransitioning else { + return + } + + for a in animators { + let fv = context.fromViews.filter { (view: UIView) -> Bool in + return a.canAnimate(view: view, isAppearing: false) + } + + let tv = context.toViews.filter { + return a.canAnimate(view: $0, isAppearing: true) + } + + transitionPairs.append((fv, tv)) + } + } +} + +internal extension MotionController { + /// Executes the preprocessors' process function. + func processContext() { + guard isTransitioning else { + return + } + + for x in preprocessors { + x.process(fromViews: context.fromViews, toViews: context.toViews) + } + } + + /** + Animates the views. Subclasses should call `prepareTransition` & + `prepareTransitionPairs` before calling `animate`. + */ + func animate() { + guard isTransitioning else { + return + } + + for (fv, tv) in transitionPairs { + for view in fv { + context.hide(view: view) + } + + for view in tv { + context.hide(view: view) + } + } + + var t: TimeInterval = 0 + var b = false + + for (i, a) in animators.enumerated() { + let d = a.animate(fromViews: transitionPairs[i].0, toViews: transitionPairs[i].1) + + if .infinity == d { + b = true + } else { + t = max(t, d) + } + } + + totalDuration = t + + if b { + update(elapsedTime: 0) + } else { + complete(after: t, isFinished: true) + } + } + + /** + Complete the transition. + - Parameter after: A TimeInterval. + - Parameter isFinished: A Boolean indicating if the transition + has completed. + */ + func complete(after: TimeInterval, isFinished: Bool) { + guard isTransitioning else { + return + } + + if after <= 0.001 { + complete(isFinished: isFinished) + return + } + + let v = (isFinished ? elapsedTime : 1 - elapsedTime) * totalDuration + + self.isFinished = isFinished + + currentAnimationDuration = after + v + beginTime = CACurrentMediaTime() - v + } + + /** + Complete the transition. + - Parameter isFinished: A Boolean indicating if the transition + has completed. + */ + func complete(isFinished: Bool) { + guard isTransitioning else { + return + } + + for a in animators { + a.clean() + } + + transitionContainer?.isUserInteractionEnabled = true + + let completion = completionCallback + + transitionObservers = nil + transitionContainer = nil + completionCallback = nil + container = nil + context = nil + beginTime = nil + elapsedTime = 0 + totalDuration = 0 + preprocessors.removeAll() + animators.removeAll() + plugins.removeAll() + transitionPairs.removeAll() + + completion?(isFinished) + } +} + +fileprivate extension MotionController { + /// Prepares the transition container. + func prepareTransitionContainer() { + guard let v = transitionContainer else { + return + } + + v.isUserInteractionEnabled = false + + // a view to hold all the animating views + container = UIView(frame: v.bounds) + v.addSubview(container!) + } + + /// Prepares the context. + func prepareContext() { + guard let v = container else { + return + } + + context = MotionContext(container: v) + } + + /// Prepares the preprocessors. + func preparePreprocessors() { + for x in [ + IgnoreSubviewTransitionsPreprocessor(), + MatchPreprocessor(), + SourcePreprocessor(), + CascadePreprocessor(), + DurationPreprocessor()] as [MotionPreprocessor] { + preprocessors.append(x) + } + + for x in preprocessors { + x.context = context + } + } + + /// Prepares the animators. + func prepareAnimators() { + animators.append(MotionTransitionAnimator()) + + if #available(iOS 10, tvOS 10, *) { + animators.append(MotionTransitionAnimator()) + } + + for v in animators { + v.context = context + } + } + + /// Prepares the plugins. + func preparePlugins() { + for x in Motion.enabledPlugins.map({ + return $0.init() + }) { + plugins.append(x) + } + + for plugin in plugins { + preprocessors.append(plugin) + animators.append(plugin) + } + } +} + +internal extension MotionController { + /** + Checks if a given plugin is enabled. + - Parameter plugin: A MotionPlugin.Type. + - Returns: A boolean indicating if the plugin is enabled or not. + */ + static func isEnabled(plugin: MotionPlugin.Type) -> Bool { + return nil != enabledPlugins.index(where: { return $0 == plugin }) + } + + /** + Enables a given plugin. + - Parameter plugin: A MotionPlugin.Type. + */ + static func enable(plugin: MotionPlugin.Type) { + disable(plugin: plugin) + enabledPlugins.append(plugin) + } + + /** + Disables a given plugin. + - Parameter plugin: A MotionPlugin.Type. + */ + static func disable(plugin: MotionPlugin.Type) { + guard let index = enabledPlugins.index(where: { return $0 == plugin }) else { + return + } + + enabledPlugins.remove(at: index) + } +} + +internal extension MotionController { + // should call this after `prepareTransitionPairs` & before `processContext` + func insert(preprocessor: MotionPreprocessor, before: T.Type) { + let i = preprocessors.index { $0 is T } ?? preprocessors.count + preprocessor.context = context + preprocessors.insert(preprocessor, at: i) + } +} diff --git a/Example/Pods/Material/Sources/Frameworks/Motion/Sources/MotionCoordinateSpace.swift b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/MotionCoordinateSpace.swift new file mode 100644 index 0000000..a00002f --- /dev/null +++ b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/MotionCoordinateSpace.swift @@ -0,0 +1,35 @@ +/* + * The MIT License (MIT) + * + * Copyright (C) 2017, Daniel Dahan and CosmicMind, Inc. . + * All rights reserved. + * + * Original Inspiration & Author + * Copyright (c) 2016 Luke Zhao + * + * 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 UIKit + +public enum MotionCoordinateSpace { + case global + case local + case sameParent +} diff --git a/Example/Pods/Material/Sources/Frameworks/Motion/Sources/MotionIndependentController.swift b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/MotionIndependentController.swift new file mode 100644 index 0000000..8e7899f --- /dev/null +++ b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/MotionIndependentController.swift @@ -0,0 +1,68 @@ +/* + * The MIT License (MIT) + * + * Copyright (C) 2017, Daniel Dahan and CosmicMind, Inc. . + * All rights reserved. + * + * Original Inspiration & Author + * Copyright (c) 2016 Luke Zhao + * + * 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 UIKit + +public class MotionIndependentController: MotionController { + /// An initializer. + public override init() { + super.init() + } + + /** + Transitions source views to their corresponding destination view + within a given root view. + - Parameter rootView: A UIView. + - Parameter fromViews: An Array of UIViews. + - Parameter toViews: An Array of UIViews. + - Parameter completion: An optional callback. + */ + public func transition(rootView: UIView, fromViews: [UIView], toViews: [UIView], completion: ((Bool) -> Void)? = nil) { + transitionContainer = rootView + completionCallback = completion + + prepareTransition() + prepareContext(fromViews: fromViews, toViews: toViews) + prepareTransitionPairs() + + animate() + } +} + +fileprivate extension MotionIndependentController { + /** + Prepares the context. + - Parameter fromViews: An Array of UIViews. + - PArameter toViews: An Array of UIViews. + */ + func prepareContext(fromViews: [UIView], toViews: [UIView]) { + context.defaultCoordinateSpace = .sameParent + context.set(fromViews: fromViews, toViews: toViews) + processContext() + } +} diff --git a/Example/Pods/Material/Sources/Frameworks/Motion/Sources/MotionPlugin.swift b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/MotionPlugin.swift new file mode 100644 index 0000000..27c3eb4 --- /dev/null +++ b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/MotionPlugin.swift @@ -0,0 +1,153 @@ +/* + * The MIT License (MIT) + * + * Copyright (C) 2017, Daniel Dahan and CosmicMind, Inc. . + * All rights reserved. + * + * Original Inspiration & Author + * Copyright (c) 2016 Luke Zhao + * + * 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 UIKit + +open class MotionPlugin: NSObject, MotionPreprocessor, MotionAnimator { + weak public var context: MotionContext! + + /** + Determines whether or not to receive `seekTo` callback on every frame. + + Default is false. + + When **requirePerFrameCallback** is **false**, the plugin needs to start its own animations inside `animate` & `resume` + The `seekTo` method is only being called during an interactive transition. + + When **requirePerFrameCallback** is **true**, the plugin will receive `seekTo` callback on every animation frame. Hence it is possible for the plugin to do per-frame animations without implementing `animate` & `resume` + */ + open var requirePerFrameCallback = false + + public override required init() {} + + /** + Called before any animation. + Override this method when you want to preprocess transitions for views + - Parameters: + - context: object holding all parsed and changed transitions, + - fromViews: A flattened list of all views from source ViewController + - toViews: A flattened list of all views from destination ViewController + + To check a view's transitions: + + context[view] + context[view, "transitionName"] + + To set a view's transitions: + + context[view] = [("transition1", ["parameter1"]), ("transition2", [])] + context[view, "transition1"] = ["parameter1", "parameter2"] + + */ + open func process(fromViews: [UIView], toViews: [UIView]) {} + + /** + - Returns: return true if the plugin can handle animating the view. + - Parameters: + - context: object holding all parsed and changed transitions, + - view: the view to check whether or not the plugin can handle the animation + - isAppearing: true if the view is isAppearing(i.e. a view in destination ViewController) + If return true, Motion won't animate and won't let any other plugins animate this view. + The view will also be hidden automatically during the animation. + */ + open func canAnimate(view: UIView, isAppearing: Bool) -> Bool { return false } + + /** + Perform the animation. + + Note: views in `fromViews` & `toViews` are hidden already. Unhide then if you need to take snapshots. + - Parameters: + - context: object holding all parsed and changed transitions, + - fromViews: A flattened list of all views from source ViewController (filtered by `canAnimate`) + - toViews: A flattened list of all views from destination ViewController (filtered by `canAnimate`) + - Returns: The duration needed to complete the animation + */ + + open func animate(fromViews: [UIView], toViews: [UIView]) -> TimeInterval { return 0 } + + /** + Called when all animations are completed. + + Should perform cleanup and release any reference + */ + open func clean() {} + + /** + For supporting interactive animation only. + + This method is called when an interactive animation is in place + The plugin should pause the animation, and seek to the given progress + - Parameters: + - elapsedTime: time of the animation to seek to. + */ + open func seek(to elapsedTime: TimeInterval) {} + + /** + For supporting interactive animation only. + + This method is called when an interactive animation is ended + The plugin should resume the animation. + - Parameters: + - elapsedTime: will be the same value since last `seekTo` + - reverse: a boolean value indicating whether or not the animation should reverse + */ + open func resume(at elapsedTime: TimeInterval, isReversed: Bool) -> TimeInterval { return 0 } + + /** + For supporting interactive animation only. + + This method is called when user wants to override animation transitions during an interactive animation + + - Parameters: + - state: the target state to override + - view: the view to override + */ + open func apply(state: MotionTransitionState, to view: UIView) {} +} + +// methods for enable/disable the current plugin +extension MotionPlugin { + public static var isEnabled: Bool { + get { + return Motion.isEnabled(plugin: self) + } + set { + if newValue { + enable() + } else { + disable() + } + } + } + public static func enable() { + Motion.enable(plugin: self) + } + public static func disable() { + Motion.disable(plugin: self) + } +} diff --git a/Example/Pods/Material/Sources/Frameworks/Motion/Sources/MotionSnapshotType.swift b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/MotionSnapshotType.swift new file mode 100644 index 0000000..90b021d --- /dev/null +++ b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/MotionSnapshotType.swift @@ -0,0 +1,52 @@ +/* + * The MIT License (MIT) + * + * Copyright (C) 2017, Daniel Dahan and CosmicMind, Inc. . + * All rights reserved. + * + * Original Inspiration & Author + * Copyright (c) 2016 Luke Zhao + * + * 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 UIKit + +public enum MotionSnapshotType { + /** + This setting will optimize for different types of views. + For custom views or views with masking, .optimizedDefault might + create snapshots that appear differently than the actual view. + In that case, use .normal or .slowRender to disable the optimization. + */ + case optimized + + /// snapshotView(afterScreenUpdates:) + case normal + + /// layer.render(in: currentContext) + case layerRender + + /** + This setting will not create a snapshot. It will animate the view directly. + This will mess up the view hierarchy, therefore, view controllers have to rebuild + their view structure after the transition finishes. + */ + case noSnapshot +} diff --git a/Example/Pods/Material/Sources/Frameworks/Motion/Sources/MotionTransition.swift b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/MotionTransition.swift new file mode 100644 index 0000000..8d7a46d --- /dev/null +++ b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/MotionTransition.swift @@ -0,0 +1,568 @@ +/* + * The MIT License (MIT) + * + * Copyright (C) 2017, Daniel Dahan and CosmicMind, Inc. . + * All rights reserved. + * + * Original Inspiration & Author + * Copyright (c) 2016 Luke Zhao + * + * 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 UIKit + +public class MotionTransition { + /// A reference to the callback that applies the MotionTransitionState. + internal let apply: (inout MotionTransitionState) -> Void + + /** + An initializer that accepts a given callback. + - Parameter applyFunction: A given callback. + */ + init(applyFunction: @escaping (inout MotionTransitionState) -> Void) { + apply = applyFunction + } +} + +public extension MotionTransition { + /** + Animates the view with a matching motion identifier. + - Parameter _ identifier: A String. + - Returns: A MotionTransition. + */ + static func motionIdentifier(_ identifier: String) -> MotionTransition { + return MotionTransition { + $0.motionIdentifier = identifier + } + } + + /** + Animates the view's current masksToBounds to the + given masksToBounds. + - Parameter masksToBounds: A boolean value indicating the + masksToBounds state. + - Returns: A MotionTransition. + */ + static func masksToBounds(_ masksToBounds: Bool) -> MotionTransition { + return MotionTransition { + $0.masksToBounds = masksToBounds + } + } + + /** + Animates the view's current background color to the + given color. + - Parameter color: A UIColor. + - Returns: A MotionTransition. + */ + static func background(color: UIColor) -> MotionTransition { + return MotionTransition { + $0.backgroundColor = color.cgColor + } + } + + /** + Animates the view's current border color to the + given color. + - Parameter color: A UIColor. + - Returns: A MotionTransition. + */ + static func border(color: UIColor) -> MotionTransition { + return MotionTransition { + $0.borderColor = color.cgColor + } + } + + /** + Animates the view's current border width to the + given width. + - Parameter width: A CGFloat. + - Returns: A MotionTransition. + */ + static func border(width: CGFloat) -> MotionTransition { + return MotionTransition { + $0.borderWidth = width + } + } + + /** + Animates the view's current corner radius to the + given radius. + - Parameter radius: A CGFloat. + - Returns: A MotionTransition. + */ + static func corner(radius: CGFloat) -> MotionTransition { + return MotionTransition { + $0.cornerRadius = radius + } + } + + /** + Animates the view's current transform (perspective, scale, rotate) + to the given one. + - Parameter _ transform: A CATransform3D. + - Returns: A MotionTransition. + */ + static func transform(_ transform: CATransform3D) -> MotionTransition { + return MotionTransition { + $0.transform = transform + } + } + + /** + Animates the view's current perspective to the given one through + a CATransform3D object. + - Parameter _ perspective: A CGFloat. + - Returns: A MotionTransition. + */ + static func perspective(_ perspective: CGFloat) -> MotionTransition { + return MotionTransition { + var t = $0.transform ?? CATransform3DIdentity + t.m34 = 1 / -perspective + $0.transform = t + } + } + + /** + Animates the view's current rotate to the given x, y, + and z values. + - Parameter x: A CGFloat. + - Parameter y: A CGFloat. + - Parameter z: A CGFloat. + - Returns: A MotionTransition. + */ + static func rotate(x: CGFloat = 0, y: CGFloat = 0, z: CGFloat = 0) -> MotionTransition { + return MotionTransition { + var t = $0.transform ?? CATransform3DIdentity + t = CATransform3DRotate(t, CGFloat(Double.pi) * x / 180, 1, 0, 0) + t = CATransform3DRotate(t, CGFloat(Double.pi) * y / 180, 0, 1, 0) + $0.transform = CATransform3DRotate(t, CGFloat(Double.pi) * z / 180, 0, 0, 1) + } + } + + /** + Animates the view's current rotate to the given point. + - Parameter _ point: A CGPoint. + - Parameter z: A CGFloat, default is 0. + - Returns: A MotionTransition. + */ + static func rotate(_ point: CGPoint, z: CGFloat = 0) -> MotionTransition { + return .rotate(x: point.x, y: point.y, z: z) + } + + /** + Rotate 2d. + - Parameter _ z: A CGFloat. + - Returns: A MotionTransition. + */ + static func rotate(_ z: CGFloat) -> MotionTransition { + return .rotate(z: z) + } + + /** + Animates the view's current scale to the given x, y, z scale values. + - Parameter x: A CGFloat. + - Parameter y: A CGFloat. + - Parameter z: A CGFloat. + - Returns: A MotionTransition. + */ + static func scale(x: CGFloat = 1, y: CGFloat = 1, z: CGFloat = 1) -> MotionTransition { + return MotionTransition { + $0.transform = CATransform3DScale($0.transform ?? CATransform3DIdentity, x, y, z) + } + } + + /** + Animates the view's current x & y scale to the given scale value. + - Parameter _ xy: A CGFloat. + - Returns: A MotionTransition. + */ + static func scale(_ xy: CGFloat) -> MotionTransition { + return .scale(x: xy, y: xy) + } + + /** + Animates the view's current translation to the given + x, y, and z values. + - Parameter x: A CGFloat. + - Parameter y: A CGFloat. + - Parameter z: A CGFloat. + - Returns: A MotionTransition. + */ + static func translate(x: CGFloat = 0, y: CGFloat = 0, z: CGFloat = 0) -> MotionTransition { + return MotionTransition { + $0.transform = CATransform3DTranslate($0.transform ?? CATransform3DIdentity, x, y, z) + } + } + + /** + Animates the view's current translation to the given + point value (x & y), and a z value. + - Parameter _ point: A CGPoint. + - Parameter z: A CGFloat, default is 0. + - Returns: A MotionTransition. + */ + static func translate(_ point: CGPoint, z: CGFloat = 0) -> MotionTransition { + return .translate(x: point.x, y: point.y, z: z) + } + + /** + Animates the view's current position to the given point. + - Parameter _ point: A CGPoint. + - Returns: A MotionTransition. + */ + static func position(_ point: CGPoint) -> MotionTransition { + return MotionTransition { + $0.position = point + } + } + + /// Forces the view to not fade during a transition. + static var forceNonFade = MotionTransition { + $0.nonFade = true + } + + /// Fades the view in during a transition. + static var fadeIn = MotionTransition.fade(1) + + /// Fades the view out during a transition. + static var fadeOut = MotionTransition.fade(0) + + /** + Animates the view's current opacity to the given one. + - Parameter to opacity: A Double. + - Returns: A MotionTransition. + */ + static func fade(_ opacity: Double) -> MotionTransition { + return MotionTransition { + $0.opacity = opacity + } + } + + /** + Animates the view's current zPosition to the given position. + - Parameter _ position: An Int. + - Returns: A MotionTransition. + */ + static func zPosition(_ position: CGFloat) -> MotionTransition { + return MotionTransition { + $0.zPosition = position + } + } + + /** + Animates the view's current size to the given one. + - Parameter _ size: A CGSize. + - Returns: A MotionTransition. + */ + static func size(_ size: CGSize) -> MotionTransition { + return MotionTransition { + $0.size = size + } + } + + /** + Animates the view's current shadow path to the given one. + - Parameter path: A CGPath. + - Returns: A MotionTransition. + */ + static func shadow(path: CGPath) -> MotionTransition { + return MotionTransition { + $0.shadowPath = path + } + } + + /** + Animates the view's current shadow color to the given one. + - Parameter color: A UIColor. + - Returns: A MotionTransition. + */ + static func shadow(color: UIColor) -> MotionTransition { + return MotionTransition { + $0.shadowColor = color.cgColor + } + } + + /** + Animates the view's current shadow offset to the given one. + - Parameter offset: A CGSize. + - Returns: A MotionTransition. + */ + static func shadow(offset: CGSize) -> MotionTransition { + return MotionTransition { + $0.shadowOffset = offset + } + } + + /** + Animates the view's current shadow opacity to the given one. + - Parameter opacity: A Float. + - Returns: A MotionTransition. + */ + static func shadow(opacity: Float) -> MotionTransition { + return MotionTransition { + $0.shadowOpacity = opacity + } + } + + /** + Animates the view's current shadow radius to the given one. + - Parameter radius: A CGFloat. + - Returns: A MotionTransition. + */ + static func shadow(radius: CGFloat) -> MotionTransition { + return MotionTransition { + $0.shadowRadius = radius + } + } + + /** + Animates the view's contents rect to the given one. + - Parameter rect: A CGRect. + - Returns: A MotionTransition. + */ + static func contents(rect: CGRect) -> MotionTransition { + return MotionTransition { + $0.contentsRect = rect + } + } + + /** + Animates the view's contents scale to the given one. + - Parameter scale: A CGFloat. + - Returns: A MotionTransition. + */ + static func contents(scale: CGFloat) -> MotionTransition { + return MotionTransition { + $0.contentsScale = scale + } + } + + /** + The duration of the view's animation. + - Parameter _ duration: A TimeInterval. + - Returns: A MotionTransition. + */ + static func duration(_ duration: TimeInterval) -> MotionTransition { + return MotionTransition { + $0.duration = duration + } + } + + /** + Sets the view's animation duration to the longest + running animation within a transition. + */ + static var preferredDurationMatchesLongest = MotionTransition.duration(.infinity) + + /** + Delays the animation of a given view. + - Parameter _ time: TimeInterval. + - Returns: A MotionTransition. + */ + static func delay(_ time: TimeInterval) -> MotionTransition { + return MotionTransition { + $0.delay = time + } + } + + /** + Sets the view's timing function for the transition. + - Parameter _ timingFunction: A CAMediaTimingFunction. + - Returns: A MotionTransition. + */ + static func timingFunction(_ timingFunction: CAMediaTimingFunction) -> MotionTransition { + return MotionTransition { + $0.timingFunction = timingFunction + } + } + + /** + Available in iOS 9+, animates a view using the spring API, + given a stiffness and damping. + - Parameter stiffness: A CGFlloat. + - Parameter damping: A CGFloat. + - Returns: A MotionTransition. + */ + @available(iOS 9, *) + static func spring(stiffness: CGFloat, damping: CGFloat) -> MotionTransition { + return MotionTransition { + $0.spring = (stiffness, damping) + } + } + + /** + Animates the natural curve of a view. A value of 1 represents + a curve in a downward direction, and a value of -1 + represents a curve in an upward direction. + - Parameter intensity: A CGFloat. + - Returns: A MotionTransition. + */ + static func arc(intensity: CGFloat = 1) -> MotionTransition { + return MotionTransition { + $0.arc = intensity + } + } + + /** + Animates subviews with an increasing delay between each animation. + - Parameter delta: A TimeInterval. + - Parameter direction: A CascadeDirection. + - Parameter animationDelayedUntilMatchedViews: A boolean indicating whether + or not to delay the subview animation until all have started. + - Returns: A MotionTransition. + */ + static func cascade(delta: TimeInterval = 0.02, direction: CascadeDirection = .topToBottom, animationDelayedUntilMatchedViews: Bool = false) -> MotionTransition { + return MotionTransition { + $0.cascade = (delta, direction, animationDelayedUntilMatchedViews) + } + } + + /** + Creates an overlay on the animating view with a given color and opacity. + - Parameter color: A UIColor. + - Parameter opacity: A CGFloat. + - Returns: A MotionTransition. + */ + static func overlay(color: UIColor, opacity: CGFloat) -> MotionTransition { + return MotionTransition { + $0.overlay = (color.cgColor, opacity) + } + } +} + +public extension MotionTransition { + /** + Apply transitions directly to the view at the start of the transition. + The transitions supplied here won't be animated. + For source views, transitions are set directly at the begining of the animation. + For destination views, they replace the target state (final appearance). + */ + static func beginWith(transitions: [MotionTransition]) -> MotionTransition { + return MotionTransition { + if $0.beginState == nil { + $0.beginState = MotionTransitionStateWrapper(state: []) + } + + $0.beginState?.state.append(contentsOf: transitions) + } + } + + /** + Apply transitions directly to the view at the start of the transition if the view is + matched with another view. The transitions supplied here won't be animated. + For source views, transitions are set directly at the begining of the animation. + For destination views, they replace the target state (final appearance). + */ + static func beginWithIfMatched(transitions: [MotionTransition]) -> MotionTransition { + return MotionTransition { + if $0.beginStateIfMatched == nil { + $0.beginStateIfMatched = [] + } + + $0.beginStateIfMatched?.append(contentsOf: transitions) + } + } + + /** + Use global coordinate space. + + When using global coordinate space. The view becomes an independent view that is not + a subview of any view. It won't move when its parent view moves, and won't be affected + by parent view attributes. + + When a view is matched, this is automatically enabled. + The `source` transition will also enable this. + */ + static var useGlobalCoordinateSpace = MotionTransition { + $0.coordinateSpace = .global + } + + /// Use same parent coordinate space. + static var useSameParentCoordinateSpace = MotionTransition { + $0.coordinateSpace = .sameParent + } + + /// Ignore all motion transition attributes for a view's direct subviews. + static var ignoreSubviewTransitions: MotionTransition = .ignoreSubviewTransitions() + + /** + Ignore all motion transition attributes for a view's subviews. + - Parameter recursive: If false, will only ignore direct subviews' transitions. + default false. + */ + static func ignoreSubviewTransitions(recursive: Bool = false) -> MotionTransition { + return MotionTransition { + $0.ignoreSubviewTransitions = recursive + } + } + + /** + This will create a snapshot optimized for different view types. + For custom views or views with masking, useOptimizedSnapshot might create snapshots + that appear differently than the actual view. + In that case, use .useNormalSnapshot or .useSlowRenderSnapshot to disable the optimization. + + This transition actually does nothing by itself since .useOptimizedSnapshot is the default. + */ + static var useOptimizedSnapshot = MotionTransition { + $0.snapshotType = .optimized + } + + /// Create a snapshot using snapshotView(afterScreenUpdates:). + static var useNormalSnapshot = MotionTransition { + $0.snapshotType = .normal + } + + /** + Create a snapshot using layer.render(in: currentContext). + This is slower than .useNormalSnapshot but gives more accurate snapshots for some views + (eg. UIStackView). + */ + static var useLayerRenderSnapshot = MotionTransition { + $0.snapshotType = .layerRender + } + + /** + Force Motion to not create any snapshots when animating this view. + This will mess up the view hierarchy, therefore, view controllers have to rebuild + their view structure after the transition finishes. + */ + static var useNoSnapshot = MotionTransition { + $0.snapshotType = .noSnapshot + } + + /** + Force the view to animate (Motion will create animation contexts & snapshots for them, so + that they can be interactive). + */ + static var forceAnimate = MotionTransition { + $0.forceAnimate = true + } + + /** + Force Motion to use scale based size animation. This will convert all .size transitions into + a .scale transition. This is to help Motion animate layers that doesn't support bounds animations. + This also gives better performance. + */ + static var useScaleBasedSizeChange = MotionTransition { + $0.useScaleBasedSizeChange = true + } +} diff --git a/Example/Pods/Material/Sources/Frameworks/Motion/Sources/MotionTransitionObserver.swift b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/MotionTransitionObserver.swift new file mode 100644 index 0000000..b2e5119 --- /dev/null +++ b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/MotionTransitionObserver.swift @@ -0,0 +1,38 @@ +/* + * The MIT License (MIT) + * + * Copyright (C) 2017, Daniel Dahan and CosmicMind, Inc. . + * All rights reserved. + * + * Original Inspiration & Author + * Copyright (c) 2016 Luke Zhao + * + * 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 Foundation + +public protocol MotionTransitionObserver { + /** + Executed when the elapsed time changes during a transition. + - Parameter transitionObserver: A MotionTransitionObserver. + - Parameter didUpdateWith elapsedTime: A TimeInterval. + */ + func motion(transitionObserver: MotionTransitionObserver, didUpdateWith elapsedTime: TimeInterval) +} diff --git a/Example/Pods/Material/Sources/Frameworks/Motion/Sources/MotionTransitionState.swift b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/MotionTransitionState.swift new file mode 100644 index 0000000..060c7af --- /dev/null +++ b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/MotionTransitionState.swift @@ -0,0 +1,208 @@ +/* + * The MIT License (MIT) + * + * Copyright (C) 2017, Daniel Dahan and CosmicMind, Inc. . + * All rights reserved. + * + * Original Inspiration & Author + * Copyright (c) 2016 Luke Zhao + * + * 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 UIKit + +internal class MotionTransitionStateWrapper { + /// A reference to a MotionTransitionState. + internal var state: MotionTransitionState + + /** + An initializer that accepts a given MotionTransitionState. + - Parameter state: A MotionTransitionState. + */ + internal init(state: MotionTransitionState) { + self.state = state + } +} + +public struct MotionTransitionState { + /// The initial state that the transition will start at. + internal var beginState: MotionTransitionStateWrapper? + + /// The start state if there is a match in the desition view controller. + public var beginStateIfMatched: [MotionTransition]? + + /// A reference to the position. + public var position: CGPoint? + + /// A reference to the size. + public var size: CGSize? + + /// A reference to the transform. + public var transform: CATransform3D? + + /// A reference to the opacity. + public var opacity: Double? + + /// A reference to the cornerRadius. + public var cornerRadius: CGFloat? + + /// A reference to the backgroundColor. + public var backgroundColor: CGColor? + + /// A reference to the zPosition. + public var zPosition: CGFloat? + + /// A reference to the contentsRect. + public var contentsRect: CGRect? + + /// A reference to the contentsScale. + public var contentsScale: CGFloat? + + /// A reference to the borderWidth. + public var borderWidth: CGFloat? + + /// A reference to the borderColor. + public var borderColor: CGColor? + + /// A reference to the shadowColor. + public var shadowColor: CGColor? + + /// A reference to the shadowOpacity. + public var shadowOpacity: Float? + + /// A reference to the shadowOffset. + public var shadowOffset: CGSize? + + /// A reference to the shadowRadius. + public var shadowRadius: CGFloat? + + /// A reference to the shadowPath. + public var shadowPath: CGPath? + + /// A boolean for the masksToBounds state. + public var masksToBounds: Bool? + + /// A boolean indicating whether to display a shadow or not. + public var displayShadow = true + + /// A reference to the overlay settings. + public var overlay: (color: CGColor, opacity: CGFloat)? + + /// A reference to the spring animation settings. + public var spring: (CGFloat, CGFloat)? + + /// A time delay on starting the animation. + public var delay: TimeInterval = 0 + + /// The duration of the animation. + public var duration: TimeInterval? + + /// The timing function value of the animation. + public var timingFunction: CAMediaTimingFunction? + + /// The arc curve value. + public var arc: CGFloat? + + /// The identifier value to match source and destination views. + public var motionIdentifier: String? + + /// The cascading animation settings. + public var cascade: (TimeInterval, CascadeDirection, Bool)? + + /** + A boolean indicating whether to ignore the subview transition + animations or not. + */ + public var ignoreSubviewTransitions: Bool? + + /// The coordinate space to transition views within. + public var coordinateSpace: MotionCoordinateSpace? + + /// Change the size of a view based on a scale factor. + public var useScaleBasedSizeChange: Bool? + + /// The type of snapshot to use. + public var snapshotType: MotionSnapshotType? + + /// Do not fade the view when transitioning. + public var nonFade = false + + /// Force an animation. + public var forceAnimate = false + + /// Custom target states. + public var custom: [String: Any]? + + /** + An initializer that accepts an Array of MotionTransitions. + - Parameter transitions: An Array of MotionTransitions. + */ + init(transitions: [MotionTransition]) { + append(contentsOf: transitions) + } +} + +extension MotionTransitionState { + /** + Adds a MotionTransition to the current state. + - Parameter _ element: A MotionTransition. + */ + public mutating func append(_ element: MotionTransition) { + element.apply(&self) + } + + /** + Adds an Array of MotionTransitions to the current state. + - Parameter contentsOf elements: An Array of MotionTransitions. + */ + public mutating func append(contentsOf elements: [MotionTransition]) { + for v in elements { + v.apply(&self) + } + } + + /** + A subscript that returns a custom value for a specified key. + - Parameter key: A String. + - Returns: An optional Any value. + */ + public subscript(key: String) -> Any? { + get { + return custom?[key] + } + set(value) { + if nil == custom { + custom = [:] + } + + custom![key] = value + } + } +} + +extension MotionTransitionState: ExpressibleByArrayLiteral { + /** + An initializer implementing the ExpressibleByArrayLiteral protocol. + - Parameter arrayLiteral elements: A list of MotionTransitions. + */ + public init(arrayLiteral elements: MotionTransition...) { + append(contentsOf: elements) + } +} diff --git a/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Preprocessors/CascadePreprocessor.swift b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Preprocessors/CascadePreprocessor.swift new file mode 100644 index 0000000..ff48f98 --- /dev/null +++ b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Preprocessors/CascadePreprocessor.swift @@ -0,0 +1,114 @@ +/* + * The MIT License (MIT) + * + * Copyright (C) 2017, Daniel Dahan and CosmicMind, Inc. . + * All rights reserved. + * + * Original Inspiration & Author + * Copyright (c) 2016 Luke Zhao + * + * 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 UIKit + +public enum CascadeDirection { + case topToBottom + case bottomToTop + case leftToRight + case rightToLeft + case radial(center:CGPoint) + case inverseRadial(center:CGPoint) + + /// Based on the cascade direction a comparator is set. + var comparator: (UIView, UIView) -> Bool { + switch self { + case .topToBottom: + return { return $0.frame.minY < $1.frame.minY } + + case .bottomToTop: + return { return $0.frame.maxY == $1.frame.maxY ? $0.frame.maxX > $1.frame.maxX : $0.frame.maxY > $1.frame.maxY } + + case .leftToRight: + return { return $0.frame.minX < $1.frame.minX } + + case .rightToLeft: + return { return $0.frame.maxX > $1.frame.maxX } + + case .radial(let center): + return { return $0.center.distance(center) < $1.center.distance(center) } + + case .inverseRadial(let center): + return { return $0.center.distance(center) > $1.center.distance(center) } + } + } +} + +class CascadePreprocessor: MotionPreprocessor { + /// A reference to a MotionContext. + weak var context: MotionContext! + + /** + Processes the transitionary views. + - Parameter fromViews: An Array of UIViews. + - Parameter toViews: An Array of UIViews. + */ + func process(fromViews: [UIView], toViews: [UIView]) { + process(views: fromViews) + process(views: toViews) + } + + /** + Process an Array of views for the cascade animation. + - Parameter views: An Array of UIViews. + */ + func process(views: [UIView]) { + for v in views { + guard let (deltaTime, direction, delayMatchedViews) = context[v]?.cascade else { + continue + } + + let parentView = v is UITableView ? v.subviews.get(0) ?? v : v + let sortedSubviews = parentView.subviews.sorted(by: direction.comparator) + + let initialDelay = context[v]!.delay + let finalDelay = TimeInterval(sortedSubviews.count) * deltaTime + initialDelay + + for (i, subview) in sortedSubviews.enumerated() { + let delay = TimeInterval(i) * deltaTime + initialDelay + + func applyDelay(view: UIView) { + if context.transitionPairedView(for: view) == nil { + context[view]?.delay = delay + + } else if delayMatchedViews, let paired = context.transitionPairedView(for: view) { + context[view]?.delay = finalDelay + context[paired]?.delay = finalDelay + } + + for subview in view.subviews { + applyDelay(view: subview) + } + } + + applyDelay(view: subview) + } + } + } +} diff --git a/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Preprocessors/DurationPreprocessor.swift b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Preprocessors/DurationPreprocessor.swift new file mode 100644 index 0000000..b8a3127 --- /dev/null +++ b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Preprocessors/DurationPreprocessor.swift @@ -0,0 +1,93 @@ +/* + * The MIT License (MIT) + * + * Copyright (C) 2017, Daniel Dahan and CosmicMind, Inc. . + * All rights reserved. + * + * Original Inspiration & Author + * Copyright (c) 2016 Luke Zhao + * + * 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 UIKit + +class DurationPreprocessor: MotionPreprocessor { + /// A reference to a MotionContext. + weak var context: MotionContext! + + /** + Processes the transitionary views. + - Parameter fromViews: An Array of UIViews. + - Parameter toViews: An Array of UIViews. + */ + func process(fromViews: [UIView], toViews: [UIView]) { + var maxDuration: TimeInterval = 0 + maxDuration = applyOptimizedDurationIfNoDuration(views:fromViews) + maxDuration = max(maxDuration, applyOptimizedDurationIfNoDuration(views:toViews)) + setDurationForInfiniteDuration(views: fromViews, duration: maxDuration) + setDurationForInfiniteDuration(views: toViews, duration: maxDuration) + } + + /** + Retrieves the optimized duration for a given UIView. + - Parameter for view: A UIView. + - Returns: A TimeInterval. + */ + func optimizedDuration(for view: UIView) -> TimeInterval { + let v = context[view]! + + return view.optimizedDuration(fromPosition: context.container.convert(view.layer.position, from: view.superview), + toPosition: v.position, + size: v.size, + transform: v.transform) + } + + /** + Applies the optimized duration for an Array of UIViews. + - Parameter views: An Array of UIViews. + - Returns: A TimeInterval. + */ + func applyOptimizedDurationIfNoDuration(views: [UIView]) -> TimeInterval { + var d: TimeInterval = 0 + + for v in views where nil != context[v] { + if nil == context[v]?.duration { + context[v]!.duration = optimizedDuration(for: v) + } + + d = .infinity == context[v]!.duration! ? + max(d, optimizedDuration(for: v)) : + max(d, context[v]!.duration!) + } + + return d + } + + /** + Sets the duration if the duration of a transition is set to `.infinity`. + - Parameter views: An Array of UIViews. + - Parameter duration: A TimeInterval. + */ + func setDurationForInfiniteDuration(views: [UIView], duration: TimeInterval) { + for v in views where .infinity == context[v]?.duration { + context[v]!.duration = duration + } + } +} diff --git a/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Preprocessors/IgnoreSubviewModifiersPreprocessor.swift b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Preprocessors/IgnoreSubviewModifiersPreprocessor.swift new file mode 100644 index 0000000..114c5b1 --- /dev/null +++ b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Preprocessors/IgnoreSubviewModifiersPreprocessor.swift @@ -0,0 +1,81 @@ +/* + * The MIT License (MIT) + * + * Copyright (C) 2017, Daniel Dahan and CosmicMind, Inc. . + * All rights reserved. + * + * Original Inspiration & Author + * Copyright (c) 2016 Luke Zhao + * + * 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 UIKit + +class IgnoreSubviewTransitionsPreprocessor: MotionPreprocessor { + /// A reference to a MotionContext. + weak var context: MotionContext! + + /** + Processes the transitionary views. + - Parameter fromViews: An Array of UIViews. + - Parameter toViews: An Array of UIViews. + */ + func process(fromViews: [UIView], toViews: [UIView]) { + process(views:fromViews) + process(views:toViews) + } + + /** + Process an Array of views for the cascade animation. + - Parameter views: An Array of UIViews. + */ + func process(views: [UIView]) { + for v in views { + guard let recursive = context[v]?.ignoreSubviewTransitions else { + continue + } + + let parentView = v is UITableView ? v.subviews.get(0) ?? v : v + + guard recursive else { + for subview in parentView.subviews { + context[subview] = nil + } + + continue + } + + cleanSubviewTransitions(for: parentView) + } + } +} + +extension IgnoreSubviewTransitionsPreprocessor { + /** + Clears the transition for a given view's subviews. + - Parameter for view: A UIView. + */ + fileprivate func cleanSubviewTransitions(for view: UIView) { + for v in view.subviews { + context[v] = nil + cleanSubviewTransitions(for: v) + } + } +} diff --git a/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Preprocessors/MatchPreprocessor.swift b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Preprocessors/MatchPreprocessor.swift new file mode 100644 index 0000000..f3f6446 --- /dev/null +++ b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Preprocessors/MatchPreprocessor.swift @@ -0,0 +1,89 @@ +/* + * The MIT License (MIT) + * + * Copyright (C) 2017, Daniel Dahan and CosmicMind, Inc. . + * All rights reserved. + * + * Original Inspiration & Author + * Copyright (c) 2016 Luke Zhao + * + * 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 UIKit + +class MatchPreprocessor: MotionPreprocessor { + /// A reference to a MotionContext. + weak var context: MotionContext! + + /** + Processes the transitionary views. + - Parameter fromViews: An Array of UIViews. + - Parameter toViews: An Array of UIViews. + */ + func process(fromViews: [UIView], toViews: [UIView]) { + for tv in toViews { + guard let i = tv.motionIdentifier, let fv = context.sourceView(for: i) else { continue } + + var tvState = context[tv] ?? MotionTransitionState() + var fvState = context[fv] ?? MotionTransitionState() + + if let v = tvState.beginStateIfMatched { + tvState.append(.beginWith(transitions: v)) + } + + if let v = fvState.beginStateIfMatched { + fvState.append(.beginWith(transitions: v)) + } + + tvState.motionIdentifier = i + tvState.opacity = 0 + + fvState.motionIdentifier = i + fvState.arc = tvState.arc + fvState.duration = tvState.duration + fvState.timingFunction = tvState.timingFunction + fvState.delay = tvState.delay + fvState.spring = tvState.spring + + let forceNonFade = tvState.nonFade || fvState.nonFade + let isNonOpaque = !fv.isOpaque || fv.alpha < 1 || !tv.isOpaque || tv.alpha < 1 + + if !forceNonFade && isNonOpaque { + // Cross fade if from/toViews are not opaque. + fvState.opacity = 0 + + } else { + // No cross fade in this case, fromView is always displayed during the transition. + fvState.opacity = nil + + /** + We dont want two shadows showing up. Therefore we disable toView's + shadow when fromView is able to display its shadow. + */ + if !fv.layer.masksToBounds && fvState.displayShadow { + tvState.displayShadow = false + } + } + + context[tv] = tvState + context[fv] = fvState + } + } +} diff --git a/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Preprocessors/MotionPreprocessor.swift b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Preprocessors/MotionPreprocessor.swift new file mode 100644 index 0000000..0876c34 --- /dev/null +++ b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Preprocessors/MotionPreprocessor.swift @@ -0,0 +1,41 @@ +/* + * The MIT License (MIT) + * + * Copyright (C) 2017, Daniel Dahan and CosmicMind, Inc. . + * All rights reserved. + * + * Original Inspiration & Author + * Copyright (c) 2016 Luke Zhao + * + * 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 UIKit + +public protocol MotionPreprocessor: class { + /// A reference to a MotionContext. + weak var context: MotionContext! { get set } + + /** + Processes the transitionary views. + - Parameter fromViews: An Array of UIViews. + - Parameter toViews: An Array of UIViews. + */ + func process(fromViews: [UIView], toViews: [UIView]) +} diff --git a/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Preprocessors/SourcePreprocessor.swift b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Preprocessors/SourcePreprocessor.swift new file mode 100644 index 0000000..0892f34 --- /dev/null +++ b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Preprocessors/SourcePreprocessor.swift @@ -0,0 +1,121 @@ +/* + * The MIT License (MIT) + * + * Copyright (C) 2017, Daniel Dahan and CosmicMind, Inc. . + * All rights reserved. + * + * Original Inspiration & Author + * Copyright (c) 2016 Luke Zhao + * + * 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 UIKit + +class SourcePreprocessor: MotionPreprocessor { + /// A reference to a MotionContext. + weak var context: MotionContext! + + /** + Processes the transitionary views. + - Parameter fromViews: An Array of UIViews. + - Parameter toViews: An Array of UIViews. + */ + func process(fromViews: [UIView], toViews: [UIView]) { + for fv in fromViews { + guard let i = context[fv]?.motionIdentifier, let tv = context.destinationView(for: i) else { + continue + } + + prepare(view: fv, for: tv) + } + + for tv in toViews { + guard let i = context[tv]?.motionIdentifier, let fv = context.sourceView(for: i) else { + continue + } + + prepare(view: tv, for: fv) + } + } + + /** + Prepares a given view for a target view. + - Parameter view: A UIView. + - Parameter for targetView: A UIView. + */ + func prepare(view: UIView, for targetView: UIView) { + let targetPos = context.container.convert(targetView.layer.position, from: targetView.superview!) + var state = context[view]! + + /** + Use global coordinate space since over target position is + converted from the global container + */ + state.coordinateSpace = .global + + // Remove incompatible options. + state.position = targetPos + state.transform = nil + state.size = nil + state.cornerRadius = nil + + if view.bounds.size != targetView.bounds.size { + state.size = targetView.bounds.size + } + + if view.layer.cornerRadius != targetView.layer.cornerRadius { + state.cornerRadius = targetView.layer.cornerRadius + } + + if view.layer.transform != targetView.layer.transform { + state.transform = targetView.layer.transform + } + + if view.layer.shadowColor != targetView.layer.shadowColor { + state.shadowColor = targetView.layer.shadowColor + } + + if view.layer.shadowOpacity != targetView.layer.shadowOpacity { + state.shadowOpacity = targetView.layer.shadowOpacity + } + + if view.layer.shadowOffset != targetView.layer.shadowOffset { + state.shadowOffset = targetView.layer.shadowOffset + } + + if view.layer.shadowRadius != targetView.layer.shadowRadius { + state.shadowRadius = targetView.layer.shadowRadius + } + + if view.layer.shadowPath != targetView.layer.shadowPath { + state.shadowPath = targetView.layer.shadowPath + } + + if view.layer.contentsRect != targetView.layer.contentsRect { + state.contentsRect = targetView.layer.contentsRect + } + + if view.layer.contentsScale != targetView.layer.contentsScale { + state.contentsScale = targetView.layer.contentsScale + } + + context[view] = state + } +} diff --git a/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Preprocessors/TransitionPreprocessor.swift b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Preprocessors/TransitionPreprocessor.swift new file mode 100644 index 0000000..552d493 --- /dev/null +++ b/Example/Pods/Material/Sources/Frameworks/Motion/Sources/Preprocessors/TransitionPreprocessor.swift @@ -0,0 +1,390 @@ +/* + * The MIT License (MIT) + * + * Copyright (C) 2017, Daniel Dahan and CosmicMind, Inc. . + * All rights reserved. + * + * Original Inspiration & Author + * Copyright (c) 2016 Luke Zhao + * + * 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 UIKit + +public enum MotionTransitionType { + public enum Direction { + case left + case right + case up + case down + } + + case none + case auto + case push(direction: Direction) + case pull(direction: Direction) + case cover(direction: Direction) + case uncover(direction: Direction) + case slide(direction: Direction) + case zoomSlide(direction: Direction) + case pageIn(direction: Direction) + case pageOut(direction: Direction) + case fade + case zoom + case zoomOut + + indirect case selectBy(presenting: MotionTransitionType, dismissing: MotionTransitionType) + + /** + Sets the presenting and dismissing transitions. + - Parameter presenting: A MotionTransitionType. + - Returns: A MotionTransitionType. + */ + public static func autoReverse(presenting: MotionTransitionType) -> MotionTransitionType { + return .selectBy(presenting: presenting, dismissing: presenting.reversed()) + } + + /// Returns a reversal transition. + func reversed() -> MotionTransitionType { + switch self { + case .push(direction: .up): + return .pull(direction: .down) + + case .push(direction: .right): + return .pull(direction: .left) + + case .push(direction: .down): + return .pull(direction: .up) + + case .push(direction: .left): + return .pull(direction: .right) + + case .pull(direction: .up): + return .push(direction: .down) + + case .pull(direction: .right): + return .push(direction: .left) + + case .pull(direction: .down): + return .push(direction: .up) + + case .pull(direction: .left): + return .push(direction: .right) + + case .cover(direction: .up): + return .uncover(direction: .down) + + case .cover(direction: .right): + return .uncover(direction: .left) + + case .cover(direction: .down): + return .uncover(direction: .up) + + case .cover(direction: .left): + return .uncover(direction: .right) + + case .uncover(direction: .up): + return .cover(direction: .down) + + case .uncover(direction: .right): + return .cover(direction: .left) + + case .uncover(direction: .down): + return .cover(direction: .up) + + case .uncover(direction: .left): + return .cover(direction: .right) + + case .slide(direction: .up): + return .slide(direction: .down) + + case .slide(direction: .down): + return .slide(direction: .up) + + case .slide(direction: .left): + return .slide(direction: .right) + + case .slide(direction: .right): + return .slide(direction: .left) + + case .zoomSlide(direction: .up): + return .zoomSlide(direction: .down) + + case .zoomSlide(direction: .down): + return .zoomSlide(direction: .up) + + case .zoomSlide(direction: .left): + return .zoomSlide(direction: .right) + + case .zoomSlide(direction: .right): + return .zoomSlide(direction: .left) + + case .pageIn(direction: .up): + return .pageOut(direction: .down) + + case .pageIn(direction: .right): + return .pageOut(direction: .left) + + case .pageIn(direction: .down): + return .pageOut(direction: .up) + + case .pageIn(direction: .left): + return .pageOut(direction: .right) + + case .pageOut(direction: .up): + return .pageIn(direction: .down) + + case .pageOut(direction: .right): + return .pageIn(direction: .left) + + case .pageOut(direction: .down): + return .pageIn(direction: .up) + + case .pageOut(direction: .left): + return .pageIn(direction: .right) + + case .zoom: + return .zoomOut + + case .zoomOut: + return .zoom + + default: + return self + } + } +} + +class TransitionPreprocessor: MotionPreprocessor { + /// A reference to a MotionContext. + weak var context: MotionContext! + + /// A reference to a Motion. + weak var motion: Motion? + + /** + An initializer that accepts a given Motion instance. + - Parameter motion: A Motion. + */ + init(motion: Motion) { + self.motion = motion + } + + /** + Processes the transitionary views. + - Parameter fromViews: An Array of UIViews. + - Parameter toViews: An Array of UIViews. + */ + func process(fromViews: [UIView], toViews: [UIView]) { + guard let m = motion else { + return + } + + guard let fv = m.fromView else { + return + } + + guard let tv = m.toView else { + return + } + + var defaultAnimation = m.defaultAnimation + let isNavigationController = m.isNavigationController + let isTabBarController = m.isTabBarController + let toViewController = m.toViewController + let fromViewController = m.fromViewController + let isPresenting = m.isPresenting + let fromOverFullScreen = m.fromOverFullScreen + let toOverFullScreen = m.toOverFullScreen + let animators = m.animators + + if case .auto = defaultAnimation { + if isNavigationController, let navAnim = toViewController?.navigationController?.motionNavigationTransitionType { + defaultAnimation = navAnim + + } else if isTabBarController, let tabAnim = toViewController?.tabBarController?.motionTabBarTransitionType { + defaultAnimation = tabAnim + + } else if let modalAnim = (isPresenting ? toViewController : fromViewController)?.motionModalTransitionType { + defaultAnimation = modalAnim + } + } + + if case .selectBy(let presentAnim, let dismissAnim) = defaultAnimation { + defaultAnimation = isPresenting ? presentAnim : dismissAnim + } + + if case .auto = defaultAnimation { + if animators.contains(where: { $0.canAnimate(view: tv, isAppearing: true) || $0.canAnimate(view: fv, isAppearing: false) }) { + defaultAnimation = .none + + } else if isNavigationController { + defaultAnimation = isPresenting ? .push(direction:.left) : .pull(direction:.right) + + } else if isTabBarController { + defaultAnimation = isPresenting ? .slide(direction:.left) : .slide(direction:.right) + + } else { + defaultAnimation = .fade + } + } + + if case .none = defaultAnimation { + return + } + + context[fv] = [.timingFunction(.standard), .duration(0.35)] + context[tv] = [.timingFunction(.standard), .duration(0.35)] + + let shadowState: [MotionTransition] = [.shadow(opacity: 0.5), + .shadow(color: .black), + .shadow(radius: 5), + .shadow(offset: .zero), + .masksToBounds(false)] + + switch defaultAnimation { + case .push(let direction): + context[tv]!.append(contentsOf: [.translate(shift(direction: direction, isAppearing: true)), + .shadow(opacity: 0), + .beginWith(transitions: shadowState), + .timingFunction(.deceleration)]) + + context[fv]!.append(contentsOf: [.translate(shift(direction: direction, isAppearing: false) / 3), + .overlay(color: .black, opacity: 0.1), + .timingFunction(.deceleration)]) + + case .pull(let direction): + m.insertToViewFirst = true + + context[fv]!.append(contentsOf: [.translate(shift(direction: direction, isAppearing: false)), + .shadow(opacity: 0), + .beginWith(transitions: shadowState)]) + + context[tv]!.append(contentsOf: [.translate(shift(direction: direction, isAppearing: true) / 3), + .overlay(color: .black, opacity: 0.1)]) + + case .slide(let direction): + context[fv]!.append(contentsOf: [.translate(shift(direction: direction, isAppearing: false))]) + + context[tv]!.append(contentsOf: [.translate(shift(direction: direction, isAppearing: true))]) + + case .zoomSlide(let direction): + context[fv]!.append(contentsOf: [.translate(shift(direction: direction, isAppearing: false)), .scale(0.8)]) + + context[tv]!.append(contentsOf: [.translate(shift(direction: direction, isAppearing: true)), .scale(0.8)]) + + case .cover(let direction): + context[tv]!.append(contentsOf: [.translate(shift(direction: direction, isAppearing: true)), + .shadow(opacity: 0), + .beginWith(transitions: shadowState), + .timingFunction(.deceleration)]) + + context[fv]!.append(contentsOf: [.overlay(color: .black, opacity: 0.1), + .timingFunction(.deceleration)]) + + case .uncover(let direction): + m.insertToViewFirst = true + + context[fv]!.append(contentsOf: [.translate(shift(direction: direction, isAppearing: false)), + .shadow(opacity: 0), + .beginWith(transitions: shadowState)]) + + context[tv]!.append(contentsOf: [.overlay(color: .black, opacity: 0.1)]) + + case .pageIn(let direction): + context[tv]!.append(contentsOf: [.translate(shift(direction: direction, isAppearing: true)), + .shadow(opacity: 0), + .beginWith(transitions: shadowState), + .timingFunction(.deceleration)]) + + context[fv]!.append(contentsOf: [.scale(0.7), + .overlay(color: .black, opacity: 0.1), + .timingFunction(.deceleration)]) + + case .pageOut(let direction): + m.insertToViewFirst = true + + context[fv]!.append(contentsOf: [.translate(shift(direction: direction, isAppearing: false)), + .shadow(opacity: 0), + .beginWith(transitions: shadowState)]) + + context[tv]!.append(contentsOf: [.scale(0.7), + .overlay(color: .black, opacity: 0.1)]) + + case .fade: + // TODO: clean up this. overFullScreen logic shouldn't be here + if !(fromOverFullScreen && !isPresenting) { + context[tv] = [.fadeOut] + } + + #if os(tvOS) + context[fromView] = [.fade] + #else + if (!isPresenting && toOverFullScreen) || !fv.isOpaque || (fv.backgroundColor?.alphaComponent ?? 1) < 1 { + context[fv] = [.fadeOut] + } + #endif + + context[tv]!.append(.preferredDurationMatchesLongest) + context[fv]!.append(.preferredDurationMatchesLongest) + + case .zoom: + m.insertToViewFirst = true + context[fv]!.append(contentsOf: [.scale(1.3), .fadeOut]) + context[tv]!.append(contentsOf: [.scale(0.7)]) + + case .zoomOut: + context[tv]!.append(contentsOf: [.scale(1.3), .fadeOut]) + context[fv]!.append(contentsOf: [.scale(0.7)]) + + default: + fatalError("Not implemented") + } + } + + /** + Shifts the transition by a given size. + - Parameter direction: A MotionTransitionType.Direction. + - Parameter isAppearing: A boolean indicating whether it is appearing + or not. + - Parameter size: An optional CGSize. + - Parameter transpose: A boolean indicating to change the `x` point for `y` + and `y` point for `x`. + - Returns: A CGPoint. + */ + func shift(direction: MotionTransitionType.Direction, isAppearing: Bool, size: CGSize? = nil, transpose: Bool = false) -> CGPoint { + let size = size ?? context.container.bounds.size + let point: CGPoint + + switch direction { + case .left, .right: + point = CGPoint(x: (.right == direction) == isAppearing ? -size.width : size.width, y: 0) + + case .up, .down: + point = CGPoint(x: 0, y: (.down == direction) == isAppearing ? -size.height : size.height) + } + + if transpose { + return CGPoint(x: point.y, y: point.x) + } + + return point + } +} diff --git a/Example/Pods/Material/Sources/iOS/Application.swift b/Example/Pods/Material/Sources/iOS/Application.swift index ec8ec86..5c934fa 100644 --- a/Example/Pods/Material/Sources/iOS/Application.swift +++ b/Example/Pods/Material/Sources/iOS/Application.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,17 +31,22 @@ import UIKit public struct Application { - /// A reference to the main UIWindow. + /// An optional reference to the main UIWindow. public static var keyWindow: UIWindow? { return UIApplication.shared.keyWindow } - /// A Boolean indicating if the device is in Landscape mode. + /// An optional reference to the top most view controller. + public static var rootViewController: UIViewController? { + return keyWindow?.rootViewController + } + + /// A boolean indicating if the device is in Landscape mode. public static var isLandscape: Bool { return UIApplication.shared.statusBarOrientation.isLandscape } - /// A Boolean indicating if the device is in Portrait mode. + /// A boolean indicating if the device is in Portrait mode. public static var isPortrait: Bool { return !isLandscape } diff --git a/Example/Pods/Material/Sources/iOS/Bar.swift b/Example/Pods/Material/Sources/iOS/Bar.swift index a55fbbd..82e1aec 100644 --- a/Example/Pods/Material/Sources/iOS/Bar.swift +++ b/Example/Pods/Material/Sources/iOS/Bar.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -39,7 +39,7 @@ public enum ContentViewAlignment: Int { open class Bar: View { /// Will layout the view. open var willLayout: Bool { - return 0 < width && 0 < height && nil != superview + return 0 < width && 0 < height && nil != superview && !grid.deferred } open override var intrinsicContentSize: CGSize { @@ -183,15 +183,6 @@ open class Bar: View { return } - guard !grid.deferred else { - return - } - - reload() - } - - /// Reloads the view. - open func reload() { var lc = 0 var rc = 0 @@ -265,21 +256,23 @@ open class Bar: View { grid.commit() contentView.grid.commit() - divider.reload() + layoutDivider() } - /** - Prepares the view instance when intialized. When subclassing, - it is recommended to override the prepare method - to initialize property values and other setup operations. - The super.prepare method should always be called immediately - when subclassing. - */ open override func prepare() { super.prepare() heightPreset = .normal autoresizingMask = .flexibleWidth interimSpacePreset = .interimSpace3 contentEdgeInsetsPreset = .square1 + + prepareContentView() + } +} + +extension Bar { + /// Prepares the contentView. + fileprivate func prepareContentView() { + contentView.contentScaleFactor = Screen.scale } } diff --git a/Example/Pods/Material/Sources/iOS/Border.swift b/Example/Pods/Material/Sources/iOS/Border.swift index 7e9aef3..508f6e5 100644 --- a/Example/Pods/Material/Sources/iOS/Border.swift +++ b/Example/Pods/Material/Sources/iOS/Border.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -42,30 +42,30 @@ public enum BorderWidthPreset: Int { case border7 case border8 case border9 -} - -/// Converts the BorderWidthPreset enum to a CGFloat value. -public func BorderWidthPresetToValue(preset: BorderWidthPreset) -> CGFloat { - switch preset { - case .none: - return 0 - case .border1: - return 0.5 - case .border2: - return 1 - case .border3: - return 2 - case .border4: - return 3 - case .border5: - return 4 - case .border6: - return 5 - case .border7: - return 6 - case .border8: - return 7 - case .border9: - return 8 - } + + /// A CGFloat representation of the border width preset. + public var cgFloatValue: CGFloat { + switch self { + case .none: + return 0 + case .border1: + return 0.5 + case .border2: + return 1 + case .border3: + return 2 + case .border4: + return 3 + case .border5: + return 4 + case .border6: + return 5 + case .border7: + return 6 + case .border8: + return 7 + case .border9: + return 8 + } + } } diff --git a/Example/Pods/Material/Sources/iOS/BottomNavigationController.swift b/Example/Pods/Material/Sources/iOS/BottomNavigationController.swift index 71ca6cb..d91bed8 100644 --- a/Example/Pods/Material/Sources/iOS/BottomNavigationController.swift +++ b/Example/Pods/Material/Sources/iOS/BottomNavigationController.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,39 +30,25 @@ import UIKit -public class BottomNavigationFadeAnimatedTransitioning: NSObject, UIViewControllerAnimatedTransitioning { - public func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { - let fromView : UIView = transitionContext.view(forKey: UITransitionContextViewKey.from)! - let toView : UIView = transitionContext.view(forKey: UITransitionContextViewKey.to)! - toView.alpha = 0 - - transitionContext.containerView.addSubview(fromView) - transitionContext.containerView.addSubview(toView) - - UIView.animate(withDuration: transitionDuration(using: transitionContext), - animations: { _ in - toView.alpha = 1 - fromView.alpha = 0 - }) { _ in - transitionContext.completeTransition(true) - } - } - - public func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { - return 0.35 - } -} - -@objc(BottomNavigationTransitionAnimation) -public enum BottomNavigationTransitionAnimation: Int { - case none - case fade +extension UIViewController { + /** + A convenience property that provides access to the BottomNavigationController. + This is the recommended method of accessing the BottomNavigationController + through child UIViewControllers. + */ + public var bottomNavigationController: BottomNavigationController? { + var viewController: UIViewController? = self + while nil != viewController { + if viewController is BottomNavigationController { + return viewController as? BottomNavigationController + } + viewController = viewController?.parent + } + return nil + } } -open class BottomNavigationController: UITabBarController, UITabBarControllerDelegate { - /// The transition animation to use when selecting a new tab. - open var transitionAnimation = BottomNavigationTransitionAnimation.fade - +open class BottomNavigationController: UITabBarController { /** An initializer that initializes the object with a NSCoder object. - Parameter aDecoder: A NSCoder instance. @@ -104,7 +90,12 @@ open class BottomNavigationController: UITabBarController, UITabBarControllerDel layoutSubviews() } - open func layoutSubviews() { + /** + To execute in the order of the layout chain, override this + method. `layoutSubviews` should be called immediately, unless you + have a certain need. + */ + open func layoutSubviews() { if let v = tabBar.items { for item in v { if .phone == Device.userInterfaceIdiom { @@ -128,7 +119,7 @@ open class BottomNavigationController: UITabBarController, UITabBarControllerDel } } - tabBar.divider.reload() + tabBar.layoutDivider() } /** @@ -138,32 +129,26 @@ open class BottomNavigationController: UITabBarController, UITabBarControllerDel The super.prepare method should always be called immediately when subclassing. */ - open func prepare() { - view.clipsToBounds = true - view.contentScaleFactor = Screen.scale - view.backgroundColor = .white - delegate = self + open func prepare() { + view.clipsToBounds = true + view.backgroundColor = .white + view.contentScaleFactor = Screen.scale + prepareTabBar() } - - /// Handles transitions when tabBarItems are pressed. - open func tabBarController(_ tabBarController: UITabBarController, animationControllerForTransitionFrom fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? { - let fVC: UIViewController? = fromVC - let tVC: UIViewController? = toVC - if nil == fVC || nil == tVC { - return nil - } - return .fade == transitionAnimation ? BottomNavigationFadeAnimatedTransitioning() : nil - } - - /// Prepares the tabBar. - private func prepareTabBar() { - tabBar.heightPreset = .normal - tabBar.depthPreset = .depth1 +} + +fileprivate extension BottomNavigationController { + /// Prepares the tabBar. + func prepareTabBar() { + tabBar.isTranslucent = false + tabBar.heightPreset = .normal + tabBar.dividerColor = Color.grey.lighten2 tabBar.dividerAlignment = .top - let image = UIImage.image(with: Color.clear, size: CGSize(width: 1, height: 1)) - tabBar.shadowImage = image - tabBar.backgroundImage = image - tabBar.backgroundColor = .white - } + + let image = UIImage() + tabBar.shadowImage = image + tabBar.backgroundImage = image + tabBar.backgroundColor = .white + } } diff --git a/Example/Pods/Material/Sources/iOS/BottomTabBar.swift b/Example/Pods/Material/Sources/iOS/BottomTabBar.swift deleted file mode 100644 index 8d55a99..0000000 --- a/Example/Pods/Material/Sources/iOS/BottomTabBar.swift +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, 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 of CosmicMind 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. - */ - -import UIKit - -extension UITabBarItem { - /// Sets the color of the title color for a state. - public func setTitleColor(color: UIColor, forState state: UIControlState) { - setTitleTextAttributes([NSForegroundColorAttributeName: color], for: state) - } -} - -open class BottomTabBar: UITabBar { - open override var intrinsicContentSize: CGSize { - return CGSize(width: width, height: height) - } - - /// Automatically aligns the BottomNavigationBar to the superview. - @IBInspectable - open var isAlignedToParentAutomatically = true - - /// A property that accesses the backing layer's background - @IBInspectable - open override var backgroundColor: UIColor? { - didSet { - barTintColor = backgroundColor - } - } - - /** - An initializer that initializes the object with a CGRect object. - If AutoLayout is used, it is better to initilize the instance - using the init() initializer. - - Parameter frame: A CGRect instance. - */ - public override init(frame: CGRect) { - super.init(frame: frame) - prepare() - } - - /// A convenience initializer. - public convenience init() { - self.init(frame: .zero) - } - - public required init?(coder aDecoder: NSCoder) { - super.init(coder: aDecoder) - prepare() - } - - open override func layoutSubviews() { - super.layoutSubviews() - layoutShape() - layoutShadowPath() - - if let v = items { - for item in v { - if .phone == Device.userInterfaceIdiom { - if nil == item.title { - let inset: CGFloat = 7 - item.imageInsets = UIEdgeInsetsMake(inset, 0, -inset, 0) - } else { - let inset: CGFloat = 6 - item.titlePositionAdjustment.vertical = -inset - } - } else if nil == item.title { - let inset: CGFloat = 9 - item.imageInsets = UIEdgeInsetsMake(inset, 0, -inset, 0) - } else { - let inset: CGFloat = 3 - item.imageInsets = UIEdgeInsetsMake(inset, 0, -inset, 0) - item.titlePositionAdjustment.vertical = -inset - } - } - } - - divider.reload() - } - - open override func didMoveToSuperview() { - super.didMoveToSuperview() - if isAlignedToParentAutomatically { - if let v = superview { - v.layout(self).bottom().horizontally() - } - } - } - - /** - Prepares the view instance when intialized. When subclassing, - it is recommended to override the prepare method - to initialize property values and other setup operations. - The super.prepare method should always be called immediately - when subclassing. - */ - public func prepare() { - heightPreset = .normal - depthPreset = .depth1 - dividerAlignment = .top - contentScaleFactor = Screen.scale - backgroundColor = .white - let image = UIImage.image(with: .clear, size: CGSize(width: 1, height: 1)) - shadowImage = image - backgroundImage = image - } -} diff --git a/Example/Pods/Material/Sources/iOS/Button.swift b/Example/Pods/Material/Sources/iOS/Button.swift index 04ef6df..24a56f0 100644 --- a/Example/Pods/Material/Sources/iOS/Button.swift +++ b/Example/Pods/Material/Sources/iOS/Button.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,7 +30,7 @@ import UIKit -open class Button: UIButton, Pulseable { +open class Button: UIButton, Pulseable, PulseableLayer { /** A CAShapeLayer used to manage elements that would be affected by the clipToBounds property of the backing layer. For example, this @@ -40,7 +40,12 @@ open class Button: UIButton, Pulseable { open let visualLayer = CAShapeLayer() /// A Pulse reference. - fileprivate var pulse: Pulse! + internal var pulse: Pulse! + + /// A reference to the pulse layer. + internal var pulseLayer: CALayer? { + return pulse.pulseLayer + } /// PulseAnimation value. open var pulseAnimation: PulseAnimation { @@ -132,7 +137,6 @@ open class Button: UIButton, Pulseable { */ public required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) - tintColor = Color.blue.base prepare() } @@ -188,11 +192,9 @@ open class Button: UIButton, Pulseable { from the center. */ open func pulse(point: CGPoint? = nil) { - let p = point ?? center - - pulse.expandAnimation(point: p) - Motion.delay(time: 0.35) { [weak self] in - self?.pulse.contractAnimation() + pulse.expand(point: point ?? center) + Motion.delay(0.35) { [weak self] in + self?.pulse.contract() } } @@ -204,7 +206,7 @@ open class Button: UIButton, Pulseable { */ open override func touchesBegan(_ touches: Set, with event: UIEvent?) { super.touchesBegan(touches, with: event) - pulse.expandAnimation(point: layer.convert(touches.first!.location(in: self), from: layer)) + pulse.expand(point: layer.convert(touches.first!.location(in: self), from: layer)) } /** @@ -215,7 +217,7 @@ open class Button: UIButton, Pulseable { */ open override func touchesEnded(_ touches: Set, with event: UIEvent?) { super.touchesEnded(touches, with: event) - pulse.contractAnimation() + pulse.contract() } /** @@ -226,7 +228,7 @@ open class Button: UIButton, Pulseable { */ open override func touchesCancelled(_ touches: Set, with event: UIEvent?) { super.touchesCancelled(touches, with: event) - pulse.contractAnimation() + pulse.contract() } open func bringImageViewToFront() { diff --git a/Example/Pods/Material/Sources/iOS/Card.swift b/Example/Pods/Material/Sources/iOS/Card.swift index cd66289..55776ac 100644 --- a/Example/Pods/Material/Sources/iOS/Card.swift +++ b/Example/Pods/Material/Sources/iOS/Card.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -198,21 +198,14 @@ open class Card: PulseView { } container.height = h - height = h + bounds.size.height = h } - /** - Prepares the view instance when intialized. When subclassing, - it is recommended to override the prepare method - to initialize property values and other setup operations. - The super.prepare method should always be called immediately - when subclassing. - */ open override func prepare() { super.prepare() - depthPreset = .depth1 pulseAnimation = .none cornerRadiusPreset = .cornerRadius1 + prepareContainer() } @@ -233,9 +226,9 @@ open class Card: PulseView { let w = container.width - insets.left - insets.right var h = view.height - if 0 == h { + if 0 == h || nil != view as? UILabel { (view as? UILabel)?.sizeToFit() - h = view.sizeThatFits(CGSize(width: w, height: CGFloat.greatestFiniteMagnitude)).height + h = view.sizeThatFits(CGSize(width: w, height: .greatestFiniteMagnitude)).height } view.width = w @@ -255,9 +248,11 @@ open class Card: PulseView { self.contentView = contentView self.bottomBar = bottomBar } - +} + +extension Card { /// Prepares the container. - private func prepareContainer() { + fileprivate func prepareContainer() { container.clipsToBounds = true addSubview(container) } diff --git a/Example/Pods/Material/Sources/iOS/EditorController.swift b/Example/Pods/Material/Sources/iOS/CardCollectionViewCell.swift similarity index 53% rename from Example/Pods/Material/Sources/iOS/EditorController.swift rename to Example/Pods/Material/Sources/iOS/CardCollectionViewCell.swift index 8b12739..e305835 100644 --- a/Example/Pods/Material/Sources/iOS/EditorController.swift +++ b/Example/Pods/Material/Sources/iOS/CardCollectionViewCell.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,55 +29,23 @@ */ import UIKit -import AVFoundation -extension UIViewController { - /** - A convenience property that provides access to the EditorController. - This is the recommended method of accessing the EditorController - through child UIViewControllers. - */ - public var editorController: EditorController? { - var viewController: UIViewController? = self - while nil != viewController { - if viewController is EditorController { - return viewController as? EditorController +open class CardCollectionViewCell: CollectionViewCell { + /// An optional reference to the card being displayed in the cell. + open var card: Card? { + didSet { + oldValue?.removeFromSuperview() + + guard let v = card else { + return } - viewController = viewController?.parent + + contentView.addSubview(v) } - return nil } -} - -open class EditorController: ToolbarController { - /// A reference to the Editor instance. - @IBInspectable - open let editor = Editor() - /** - Prepares the view instance when intialized. When subclassing, - it is recommended to override the prepare method - to initialize property values and other setup operations. - The super.prepare method should always be called immediately - when subclassing. - */ open override func prepare() { super.prepare() - view.backgroundColor = .white - - prepareToolbar() - prepareEditor() - } - - /// Prepares the toolbar. - private func prepareToolbar() { - toolbar.depthPreset = .none - } - - /// Prepares editor. - private func prepareEditor() { - editor.delegate = self + pulseAnimation = .none } } - -extension EditorController: EditorDelegate {} diff --git a/Example/Pods/Material/Sources/iOS/CardCollectionViewController.swift b/Example/Pods/Material/Sources/iOS/CardCollectionViewController.swift new file mode 100644 index 0000000..c759728 --- /dev/null +++ b/Example/Pods/Material/Sources/iOS/CardCollectionViewController.swift @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, 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 of CosmicMind 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. + */ + +import UIKit + +extension UIViewController { + /** + A convenience property that provides access to the CardCollectionViewController. + This is the recommended method of accessing the CardCollectionViewController + through child UIViewControllers. + */ + public var cardCollectionViewController: CardCollectionViewController? { + var viewController: UIViewController? = self + while nil != viewController { + if viewController is CardCollectionViewController { + return viewController as? CardCollectionViewController + } + viewController = viewController?.parent + } + return nil + } +} + +open class CardCollectionViewController: UIViewController { + /// A reference to a Reminder. + open let collectionView = CollectionView() + + open var dataSourceItems = [DataSourceItem]() + + /// An index of IndexPath to DataSourceItem. + open var dataSourceItemsIndexPaths = [IndexPath: Any]() + + open override func viewDidLoad() { + super.viewDidLoad() + prepare() + } + + open override func viewWillLayoutSubviews() { + super.viewWillLayoutSubviews() + layoutSubviews() + } + + /** + Prepares the view instance when intialized. When subclassing, + it is recommended to override the prepareView method + to initialize property values and other setup operations. + The super.prepareView method should always be called immediately + when subclassing. + */ + open func prepare() { + view.clipsToBounds = true + view.backgroundColor = .white + view.contentScaleFactor = Screen.scale + prepareCollectionView() + } + + /// Calls the layout functions for the view heirarchy. + open func layoutSubviews() { + layoutCollectionView() + } +} + +extension CardCollectionViewController { + /// Prepares the collectionView. + fileprivate func prepareCollectionView() { + collectionView.delegate = self + collectionView.dataSource = self + collectionView.register(CardCollectionViewCell.self, forCellWithReuseIdentifier: "CardCollectionViewCell") + view.addSubview(collectionView) + layoutCollectionView() + } +} + +extension CardCollectionViewController { + /// Sets the frame for the collectionView. + fileprivate func layoutCollectionView() { + collectionView.frame = view.bounds + } +} + +extension CardCollectionViewController: CollectionViewDelegate {} + +extension CardCollectionViewController: CollectionViewDataSource { + @objc + open func numberOfSections(in collectionView: UICollectionView) -> Int { + return 1 + } + + @objc + open func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + return dataSourceItems.count + } + + @objc + open func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "CardCollectionViewCell", for: indexPath) as! CardCollectionViewCell + + guard let card = dataSourceItems[indexPath.item].data as? Card else { + return cell + } + + dataSourceItemsIndexPaths[indexPath] = card + + card.frame = cell.bounds + + cell.card = card + + return cell + } +} + diff --git a/Example/Pods/Material/Sources/iOS/CharacterAttribute.swift b/Example/Pods/Material/Sources/iOS/CharacterAttribute.swift index f8d52ba..47d573a 100644 --- a/Example/Pods/Material/Sources/iOS/CharacterAttribute.swift +++ b/Example/Pods/Material/Sources/iOS/CharacterAttribute.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -108,7 +108,7 @@ extension NSMutableAttributedString { - Parameter value: Any type. - Parameter range: A NSRange. */ - open func addAttribute(characterAttribute: CharacterAttribute, value: Any, range: NSRange) { + open func add(characterAttribute: CharacterAttribute, value: Any, range: NSRange) { addAttribute(CharacterAttributeToValue(attribute: characterAttribute), value: value, range: range) } @@ -117,9 +117,9 @@ extension NSMutableAttributedString { - Parameter characterAttributes: A Dictionary of CharacterAttribute type keys and Any type values. - Parameter range: A NSRange. */ - open func addAttributes(characterAttributes: [CharacterAttribute : Any] = [:], range: NSRange) { + open func add(characterAttributes: [CharacterAttribute: Any], range: NSRange) { for (k, v) in characterAttributes { - addAttribute(characterAttribute: k, value: v, range: range) + add(characterAttribute: k, value: v, range: range) } } @@ -129,9 +129,9 @@ extension NSMutableAttributedString { - Parameter value: Any type. - Parameter range: A NSRange. */ - open func updateAttribute(characterAttribute: CharacterAttribute, value: Any, range: NSRange) { - removeAttribute(characterAttribute: characterAttribute, range: range) - addAttribute(characterAttribute: characterAttribute, value: value, range: range) + open func update(characterAttribute: CharacterAttribute, value: Any, range: NSRange) { + remove(characterAttribute: characterAttribute, range: range) + add(characterAttribute: characterAttribute, value: value, range: range) } /** @@ -139,9 +139,9 @@ extension NSMutableAttributedString { - Parameter characterAttributes: A Dictionary of CharacterAttribute type keys and Any type values. - Parameter range: A NSRange. */ - open func updateAttributes(characterAttributes: [CharacterAttribute : Any] = [:], range: NSRange) { + open func update(characterAttributes: [CharacterAttribute: Any], range: NSRange) { for (k, v) in characterAttributes { - updateAttribute(characterAttribute: k, value: v, range: range) + update(characterAttribute: k, value: v, range: range) } } @@ -150,7 +150,7 @@ extension NSMutableAttributedString { - Parameter characterAttribute: A CharacterAttribute. - Parameter range: A NSRange. */ - open func removeAttribute(characterAttribute: CharacterAttribute, range: NSRange) { + open func remove(characterAttribute: CharacterAttribute, range: NSRange) { removeAttribute(CharacterAttributeToValue(attribute: characterAttribute), range: range) } @@ -159,9 +159,9 @@ extension NSMutableAttributedString { - Parameter characterAttributes: An Array of CharacterAttributes. - Parameter range: A NSRange. */ - open func removeAttributes(characterAttributes: [CharacterAttribute] = [], range: NSRange) { + open func remove(characterAttributes: [CharacterAttribute], range: NSRange) { for k in characterAttributes { - removeAttribute(characterAttribute: k, range: range) + remove(characterAttribute: k, range: range) } } } diff --git a/Example/Pods/Material/Sources/iOS/ChipBar.swift b/Example/Pods/Material/Sources/iOS/ChipBar.swift new file mode 100644 index 0000000..0382601 --- /dev/null +++ b/Example/Pods/Material/Sources/iOS/ChipBar.swift @@ -0,0 +1,378 @@ +/* + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, 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 of CosmicMind 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. + */ + +import UIKit + +@objc(ChipItemStyle) +public enum ChipItemStyle: Int { + case pill +} + +open class ChipItem: FlatButton { + /// Configures the visual display of the chip. + var chipItemStyle: ChipItemStyle { + get { + return associatedInstance.chipItemStyle + } + set(value) { + associatedInstance.chipItemStyle = value + layoutSubviews() + } + } + + open override func layoutSubviews() { + super.layoutSubviews() + layoutChipItemStyle() + } + + open override func prepare() { + super.prepare() + pulseAnimation = .none + } +} + +fileprivate extension ChipItem { + /// Lays out the chipItem based on its style. + func layoutChipItemStyle() { + if .pill == chipItemStyle { + cornerRadius = height / 2 + } + } +} + +fileprivate struct AssociatedInstance { + /// A ChipItemStyle value. + var chipItemStyle: ChipItemStyle +} + +/// A memory reference to the ChipItemStyle instance for ChipItem extensions. +fileprivate var ChipKey: UInt8 = 0 + +fileprivate extension ChipItem { + /// AssociatedInstance reference. + var associatedInstance: AssociatedInstance { + get { + return AssociatedObject.get(base: self, key: &ChipKey) { + return AssociatedInstance(chipItemStyle: .pill) + } + } + set(value) { + AssociatedObject.set(base: self, key: &ChipKey, value: value) + } + } +} + +@objc(ChipBarDelegate) +public protocol ChipBarDelegate { + /** + A delegation method that is executed when the chipItem will trigger the + animation to the next chip. + - Parameter chipBar: A ChipBar. + - Parameter chipItem: A ChipItem. + */ + @objc + optional func chipBar(chipBar: ChipBar, willSelect chipItem: ChipItem) + + /** + A delegation method that is executed when the chipItem did complete the + animation to the next chip. + - Parameter chipBar: A ChipBar. + - Parameter chipItem: A ChipItem. + */ + @objc + optional func chipBar(chipBar: ChipBar, didSelect chipItem: ChipItem) +} + +@objc(ChipBarStyle) +public enum ChipBarStyle: Int { + case auto + case nonScrollable + case scrollable +} + +open class ChipBar: Bar { + /// The total width of the chipItems. + fileprivate var chipItemsTotalWidth: CGFloat { + var w: CGFloat = 0 + let q = 2 * chipItemsInterimSpace + let p = q + chipItemsInterimSpace + + for v in chipItems { + let x = v.sizeThatFits(CGSize(width: .greatestFiniteMagnitude, height: scrollView.height)).width + w += x + w += p + } + + w -= chipItemsInterimSpace + + return w + } + + /// An enum that determines the chip bar style. + open var chipBarStyle = ChipBarStyle.auto { + didSet { + layoutSubviews() + } + } + + /// A reference to the scroll view when the chip bar style is scrollable. + open let scrollView = UIScrollView() + + /// Enables and disables bouncing when swiping. + open var isScrollBounceEnabled: Bool { + get { + return scrollView.bounces + } + set(value) { + scrollView.bounces = value + } + } + + /// A delegation reference. + open weak var delegate: ChipBarDelegate? + + /// The currently selected chipItem. + open fileprivate(set) var selectedChipItem: ChipItem? + + /// A preset wrapper around chipItems contentEdgeInsets. + open var chipItemsContentEdgeInsetsPreset: EdgeInsetsPreset { + get { + return contentView.grid.contentEdgeInsetsPreset + } + set(value) { + contentView.grid.contentEdgeInsetsPreset = value + } + } + + /// A reference to EdgeInsets. + @IBInspectable + open var chipItemsContentEdgeInsets: EdgeInsets { + get { + return contentView.grid.contentEdgeInsets + } + set(value) { + contentView.grid.contentEdgeInsets = value + } + } + + /// A preset wrapper around chipItems interimSpace. + open var chipItemsInterimSpacePreset: InterimSpacePreset { + get { + return contentView.grid.interimSpacePreset + } + set(value) { + contentView.grid.interimSpacePreset = value + } + } + + /// A wrapper around chipItems interimSpace. + @IBInspectable + open var chipItemsInterimSpace: InterimSpace { + get { + return contentView.grid.interimSpace + } + set(value) { + contentView.grid.interimSpace = value + } + } + + /// Buttons. + open var chipItems = [ChipItem]() { + didSet { + for b in oldValue { + b.removeFromSuperview() + } + + prepareChipItems() + layoutSubviews() + } + } + + open override func layoutSubviews() { + super.layoutSubviews() + guard willLayout else { + return + } + + layoutScrollView() + + updateScrollView() + } + + open override func prepare() { + super.prepare() + interimSpacePreset = .interimSpace3 + contentEdgeInsetsPreset = .square1 + chipItemsInterimSpacePreset = .interimSpace4 + chipItemsContentEdgeInsetsPreset = .square2 + chipItemsContentEdgeInsets.left = 0 + chipItemsContentEdgeInsets.right = 0 + + prepareContentView() + prepareScrollView() + prepareDivider() + } +} + +fileprivate extension ChipBar { + /// Prepares the divider. + func prepareDivider() { + dividerColor = Color.grey.lighten2 + } + + /// Prepares the chipItems. + func prepareChipItems() { + for v in chipItems { + v.grid.columns = 0 + v.cornerRadius = 0 + v.contentEdgeInsets = .zero + + v.removeTarget(self, action: #selector(handle(chipItem:)), for: .touchUpInside) + v.addTarget(self, action: #selector(handle(chipItem:)), for: .touchUpInside) + } + } + + /// Prepares the contentView. + func prepareContentView() { + contentView.zPosition = 6000 + } + + /// Prepares the scroll view. + func prepareScrollView() { + scrollView.showsVerticalScrollIndicator = false + scrollView.showsHorizontalScrollIndicator = false + centerViews = [scrollView] + } +} + +fileprivate extension ChipBar { + /// Layout the scrollView. + func layoutScrollView() { + contentView.grid.reload() + + if .scrollable == chipBarStyle || (.auto == chipBarStyle && chipItemsTotalWidth > scrollView.width) { + var w: CGFloat = 0 + let q = 2 * chipItemsInterimSpace + let p = q + chipItemsInterimSpace + + for v in chipItems { + let x = v.sizeThatFits(CGSize(width: .greatestFiniteMagnitude, height: scrollView.height)).width + v.height = scrollView.height + v.width = x + q + v.x = w + w += x + w += p + + if scrollView != v.superview { + v.removeFromSuperview() + scrollView.addSubview(v) + } + } + + w -= chipItemsInterimSpace + + scrollView.contentSize = CGSize(width: w, height: scrollView.height) + + } else { + scrollView.grid.begin() + scrollView.grid.views = chipItems + scrollView.grid.axis.columns = chipItems.count + scrollView.grid.contentEdgeInsets = chipItemsContentEdgeInsets + scrollView.grid.interimSpace = chipItemsInterimSpace + scrollView.grid.commit() + scrollView.contentSize = scrollView.frame.size + } + } +} + +fileprivate extension ChipBar { + /// Handles the chipItem touch event. + @objc + func handle(chipItem: ChipItem) { + animate(to: chipItem, isTriggeredByUserInteraction: true) + } +} + +extension ChipBar { + /** + Selects a given index from the chipItems array. + - Parameter at index: An Int. + - Paramater completion: An optional completion block. + */ + open func select(at index: Int, completion: ((ChipItem) -> Void)? = nil) { + guard -1 < index, index < chipItems.count else { + return + } + + animate(to: chipItems[index], isTriggeredByUserInteraction: false, completion: completion) + } + + /** + Animates to a given chipItem. + - Parameter to chipItem: A ChipItem. + - Parameter completion: An optional completion block. + */ + open func animate(to chipItem: ChipItem, completion: ((ChipItem) -> Void)? = nil) { + animate(to: chipItem, isTriggeredByUserInteraction: false, completion: completion) + } +} + +fileprivate extension ChipBar { + /** + Animates to a given chipItem. + - Parameter to chipItem: A ChipItem. + - Parameter isTriggeredByUserInteraction: A boolean indicating whether the + state was changed by a user interaction, true if yes, false otherwise. + - Parameter completion: An optional completion block. + */ + func animate(to chipItem: ChipItem, isTriggeredByUserInteraction: Bool, completion: ((ChipItem) -> Void)? = nil) { + if isTriggeredByUserInteraction { + delegate?.chipBar?(chipBar: self, willSelect: chipItem) + } + + selectedChipItem = chipItem + updateScrollView() + } +} + +fileprivate extension ChipBar { + /// Updates the scrollView. + func updateScrollView() { + guard let v = selectedChipItem else { + return + } + + if !scrollView.bounds.contains(v.frame) { + let contentOffsetX = (v.x < scrollView.bounds.minX) ? v.x : v.frame.maxX - scrollView.bounds.width + let normalizedOffsetX = min(max(contentOffsetX, 0), scrollView.contentSize.width - scrollView.bounds.width) + scrollView.setContentOffset(CGPoint(x: normalizedOffsetX, y: 0), animated: true) + } + } +} diff --git a/Example/Pods/Material/Sources/iOS/ChipBarController.swift b/Example/Pods/Material/Sources/iOS/ChipBarController.swift new file mode 100644 index 0000000..8163d1d --- /dev/null +++ b/Example/Pods/Material/Sources/iOS/ChipBarController.swift @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, 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 of CosmicMind 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. + */ + +import UIKit + +fileprivate var ChipItemKey: UInt8 = 0 + +@objc(ChipBarAlignment) +public enum ChipBarAlignment: Int { + case top + case bottom + case hidden +} + +extension UIViewController { + /** + A convenience property that provides access to the ChipBarController. + This is the recommended method of accessing the ChipBarController + through child UIViewControllers. + */ + public var chipsController: ChipBarController? { + return traverseViewControllerHierarchyForClassType() + } +} + +open class ChipBarController: TransitionController { + /** + A Display value to indicate whether or not to + display the rootViewController to the full view + bounds, or up to the toolbar height. + */ + open var displayStyle = DisplayStyle.partial { + didSet { + layoutSubviews() + } + } + + /// The ChipBar used to switch between view controllers. + @IBInspectable + open let chipBar = ChipBar() + + /// The chipBar alignment. + open var chipBarAlignment = ChipBarAlignment.bottom { + didSet { + layoutSubviews() + } + } + + open override func layoutSubviews() { + super.layoutSubviews() + layoutChipBar() + layoutContainer() + layoutRootViewController() + } + + open override func prepare() { + super.prepare() + prepareChipBar() + } +} + +fileprivate extension ChipBarController { + /// Prepares the ChipBar. + func prepareChipBar() { + chipBar.depthPreset = .depth1 + view.addSubview(chipBar) + } +} + +fileprivate extension ChipBarController { + /// Layout the container. + func layoutContainer() { + chipBar.width = view.width + + switch displayStyle { + case .partial: + let p = chipBar.height + let y = view.height - p + + switch chipBarAlignment { + case .top: + container.y = p + container.height = y + case .bottom: + container.y = 0 + container.height = y + case .hidden: + container.y = 0 + container.height = view.height + } + + container.width = view.width + + case .full: + container.frame = view.bounds + } + } + + /// Layout the chipBar. + func layoutChipBar() { + chipBar.width = view.width + + switch chipBarAlignment { + case .top: + chipBar.isHidden = false + chipBar.y = 0 + case .bottom: + chipBar.isHidden = false + chipBar.y = view.height - chipBar.height + case .hidden: + chipBar.isHidden = true + } + } + + /// Layout the rootViewController. + func layoutRootViewController() { + rootViewController.view.frame = container.bounds + } +} diff --git a/Example/Pods/Material/Sources/iOS/CollectionReusableView.swift b/Example/Pods/Material/Sources/iOS/CollectionReusableView.swift index 8cb01c4..35efe95 100644 --- a/Example/Pods/Material/Sources/iOS/CollectionReusableView.swift +++ b/Example/Pods/Material/Sources/iOS/CollectionReusableView.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,7 +31,7 @@ import UIKit @objc(CollectionReusableView) -open class CollectionReusableView: UICollectionReusableView, Pulseable { +open class CollectionReusableView: UICollectionReusableView, Pulseable, PulseableLayer { /** A CAShapeLayer used to manage elements that would be affected by the clipToBounds property of the backing layer. For example, this @@ -41,7 +41,12 @@ open class CollectionReusableView: UICollectionReusableView, Pulseable { open let visualLayer = CAShapeLayer() /// A Pulse reference. - fileprivate var pulse: Pulse! + internal var pulse: Pulse! + + /// A reference to the pulse layer. + internal var pulseLayer: CALayer? { + return pulse.pulseLayer + } /// PulseAnimation value. open var pulseAnimation: PulseAnimation { @@ -240,11 +245,9 @@ open class CollectionReusableView: UICollectionReusableView, Pulseable { from the center. */ open func pulse(point: CGPoint? = nil) { - let p = point ?? center - - pulse.expandAnimation(point: p) - Motion.delay(time: 0.35) { [weak self] in - self?.pulse.contractAnimation() + pulse.expand(point: point ?? center) + Motion.delay(0.35) { [weak self] in + self?.pulse.contract() } } @@ -256,7 +259,7 @@ open class CollectionReusableView: UICollectionReusableView, Pulseable { */ open override func touchesBegan(_ touches: Set, with event: UIEvent?) { super.touchesBegan(touches, with: event) - pulse.expandAnimation(point: layer.convert(touches.first!.location(in: self), from: layer)) + pulse.expand(point: layer.convert(touches.first!.location(in: self), from: layer)) } /** @@ -267,7 +270,7 @@ open class CollectionReusableView: UICollectionReusableView, Pulseable { */ open override func touchesEnded(_ touches: Set, with event: UIEvent?) { super.touchesEnded(touches, with: event) - pulse.contractAnimation() + pulse.contract() } /** @@ -278,7 +281,7 @@ open class CollectionReusableView: UICollectionReusableView, Pulseable { */ open override func touchesCancelled(_ touches: Set, with event: UIEvent?) { super.touchesCancelled(touches, with: event) - pulse.contractAnimation() + pulse.contract() } /** diff --git a/Example/Pods/Material/Sources/iOS/CollectionView.swift b/Example/Pods/Material/Sources/iOS/CollectionView.swift index 5bf3939..8a91a54 100644 --- a/Example/Pods/Material/Sources/iOS/CollectionView.swift +++ b/Example/Pods/Material/Sources/iOS/CollectionView.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -99,6 +99,15 @@ open class CollectionView: UICollectionView { super.init(frame: frame, collectionViewLayout: layout) prepare() } + + /** + An initializer that initializes the object. + - Parameter collectionViewLayout: A UICollectionViewLayout reference. + */ + public init(collectionViewLayout layout: UICollectionViewLayout) { + super.init(frame: .zero, collectionViewLayout: layout) + prepare() + } /** An initializer that initializes the object. @@ -106,12 +115,13 @@ open class CollectionView: UICollectionView { */ public init(frame: CGRect) { super.init(frame: frame, collectionViewLayout: CollectionViewLayout()) - prepare() - } + prepare() + } /// A convenience initializer that initializes the object. - public convenience init() { - self.init(frame: .zero) + public init() { + super.init(frame: .zero, collectionViewLayout: CollectionViewLayout()) + prepare() } /** @@ -121,8 +131,9 @@ open class CollectionView: UICollectionView { The super.prepare method should always be called immediately when subclassing. */ - open func prepare() { + open func prepare() { + backgroundColor = .white contentScaleFactor = Screen.scale - backgroundColor = .white + register(CollectionViewCell.self, forCellWithReuseIdentifier: "CollectionViewCell") } } diff --git a/Example/Pods/Material/Sources/iOS/CollectionViewCell.swift b/Example/Pods/Material/Sources/iOS/CollectionViewCell.swift index c55df41..feccf35 100644 --- a/Example/Pods/Material/Sources/iOS/CollectionViewCell.swift +++ b/Example/Pods/Material/Sources/iOS/CollectionViewCell.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,7 +31,7 @@ import UIKit @objc(CollectionViewCell) -open class CollectionViewCell: UICollectionViewCell, Pulseable { +open class CollectionViewCell: UICollectionViewCell, Pulseable, PulseableLayer { /** A CAShapeLayer used to manage elements that would be affected by the clipToBounds property of the backing layer. For example, this @@ -41,7 +41,12 @@ open class CollectionViewCell: UICollectionViewCell, Pulseable { open let visualLayer = CAShapeLayer() /// A Pulse reference. - fileprivate var pulse: Pulse! + internal var pulse: Pulse! + + /// A reference to the pulse layer. + internal var pulseLayer: CALayer? { + return pulse.pulseLayer + } /// PulseAnimation value. open var pulseAnimation: PulseAnimation { @@ -198,11 +203,9 @@ open class CollectionViewCell: UICollectionViewCell, Pulseable { from the center. */ open func pulse(point: CGPoint? = nil) { - let p = point ?? center - - pulse.expandAnimation(point: p) - Motion.delay(time: 0.35) { [weak self] in - self?.pulse.contractAnimation() + pulse.expand(point: point ?? center) + Motion.delay(0.35) { [weak self] in + self?.pulse.contract() } } @@ -214,7 +217,7 @@ open class CollectionViewCell: UICollectionViewCell, Pulseable { */ open override func touchesBegan(_ touches: Set, with event: UIEvent?) { super.touchesBegan(touches, with: event) - pulse.expandAnimation(point: layer.convert(touches.first!.location(in: self), from: layer)) + pulse.expand(point: layer.convert(touches.first!.location(in: self), from: layer)) } /** @@ -225,7 +228,7 @@ open class CollectionViewCell: UICollectionViewCell, Pulseable { */ open override func touchesEnded(_ touches: Set, with event: UIEvent?) { super.touchesEnded(touches, with: event) - pulse.contractAnimation() + pulse.contract() } /** @@ -236,7 +239,7 @@ open class CollectionViewCell: UICollectionViewCell, Pulseable { */ open override func touchesCancelled(_ touches: Set, with event: UIEvent?) { super.touchesCancelled(touches, with: event) - pulse.contractAnimation() + pulse.contract() } /** @@ -247,7 +250,9 @@ open class CollectionViewCell: UICollectionViewCell, Pulseable { when subclassing. */ open func prepare() { + backgroundColor = .white contentScaleFactor = Screen.scale + prepareVisualLayer() preparePulse() } diff --git a/Example/Pods/Material/Sources/iOS/CollectionViewController.swift b/Example/Pods/Material/Sources/iOS/CollectionViewController.swift index 2960f7a..d8e2b38 100644 --- a/Example/Pods/Material/Sources/iOS/CollectionViewController.swift +++ b/Example/Pods/Material/Sources/iOS/CollectionViewController.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -69,6 +69,11 @@ open class CollectionViewController: UIViewController { prepare() } + open override func viewWillLayoutSubviews() { + super.viewWillLayoutSubviews() + layoutSubviews() + } + /** Prepares the view instance when intialized. When subclassing, it is recommended to override the prepareView method @@ -82,6 +87,11 @@ open class CollectionViewController: UIViewController { view.contentScaleFactor = Screen.scale prepareCollectionView() } + + /// Calls the layout functions for the view heirarchy. + open func layoutSubviews() { + layoutCollectionView() + } } extension CollectionViewController { @@ -89,11 +99,19 @@ extension CollectionViewController { fileprivate func prepareCollectionView() { collectionView.delegate = self collectionView.dataSource = self - view.layout(collectionView).edges() + view.addSubview(collectionView) + } +} + +extension CollectionViewController { + /// Sets the frame for the collectionView. + fileprivate func layoutCollectionView() { + collectionView.frame = view.bounds } } extension CollectionViewController: CollectionViewDelegate {} + extension CollectionViewController: CollectionViewDataSource { @objc open func numberOfSections(in collectionView: UICollectionView) -> Int { @@ -107,6 +125,6 @@ extension CollectionViewController: CollectionViewDataSource { @objc open func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { - return UICollectionViewCell() + return collectionView.dequeueReusableCell(withReuseIdentifier: "CollectionViewCell", for: indexPath) } } diff --git a/Example/Pods/Material/Sources/iOS/CollectionViewLayout.swift b/Example/Pods/Material/Sources/iOS/CollectionViewLayout.swift index 68bda4f..f50225c 100644 --- a/Example/Pods/Material/Sources/iOS/CollectionViewLayout.swift +++ b/Example/Pods/Material/Sources/iOS/CollectionViewLayout.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -32,131 +32,182 @@ import UIKit open class CollectionViewLayout: UICollectionViewLayout { /// Used to calculate the dimensions of the cells. - open var offset = CGPoint.zero + public var offset = CGPoint.zero /// The size of items. - open var itemSize = CGSize.zero + public var itemSize = CGSize.zero /// A preset wrapper around contentEdgeInsets. - open var contentEdgeInsetsPreset = EdgeInsetsPreset.none { + public var contentEdgeInsetsPreset = EdgeInsetsPreset.none { didSet { contentEdgeInsets = EdgeInsetsPresetToValue(preset: contentEdgeInsetsPreset) } } /// A wrapper around grid.contentEdgeInsets. - open var contentEdgeInsets = EdgeInsets.zero + public var contentEdgeInsets = EdgeInsets.zero /// Size of the content. - open fileprivate(set) var contentSize = CGSize.zero + public fileprivate(set) var contentSize = CGSize.zero /// Layout attribute items. - open fileprivate(set) lazy var layoutItems = [(UICollectionViewLayoutAttributes, NSIndexPath)]() + public fileprivate(set) lazy var layoutItems = [(UICollectionViewLayoutAttributes, NSIndexPath)]() /// Cell data source items. - open fileprivate(set) var dataSourceItems: [DataSourceItem]? + public fileprivate(set) var dataSourceItems: [DataSourceItem]? /// Scroll direction. - open var scrollDirection = UICollectionViewScrollDirection.vertical + public var scrollDirection = UICollectionViewScrollDirection.vertical /// A preset wrapper around interimSpace. - open var interimSpacePreset = InterimSpacePreset.none { + public var interimSpacePreset = InterimSpacePreset.none { didSet { interimSpace = InterimSpacePresetToValue(preset: interimSpacePreset) } } /// Spacing between items. - open var interimSpace: InterimSpace = 0 + public var interimSpace: InterimSpace = 0 open override var collectionViewContentSize: CGSize { return contentSize } - - /** - Retrieves the index paths for the items within the passed in CGRect. - - Parameter rect: A CGRect that acts as the bounds to find the items within. - - Returns: An Array of NSIndexPath objects. - */ - open func indexPathsOfItemsInRect(rect: CGRect) -> [NSIndexPath] { - var paths = [NSIndexPath]() - for (attribute, indexPath) in layoutItems { - if rect.intersects(attribute.frame) { - paths.append(indexPath) - } - } - return paths - } - - open override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? { - let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath) - let item = dataSourceItems![indexPath.item] - - if 0 < itemSize.width && 0 < itemSize.height { - attributes.frame = CGRect(x: offset.x, y: offset.y, width: itemSize.width - contentEdgeInsets.left - contentEdgeInsets.right, height: itemSize.height - contentEdgeInsets.top - contentEdgeInsets.bottom) - } else if .vertical == scrollDirection { - attributes.frame = CGRect(x: contentEdgeInsets.left, y: offset.y, width: collectionView!.bounds.width - contentEdgeInsets.left - contentEdgeInsets.right, height: item.height ?? collectionView!.bounds.height) - } else { - attributes.frame = CGRect(x: offset.x, y: contentEdgeInsets.top, width: item.width ?? collectionView!.bounds.width, height: collectionView!.bounds.height - contentEdgeInsets.top - contentEdgeInsets.bottom) - } - - return attributes - } - - open override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? { - var layoutAttributes = [UICollectionViewLayoutAttributes]() - for (attribute, _) in layoutItems { - if rect.intersects(attribute.frame) { - layoutAttributes.append(attribute) - } - } - return layoutAttributes - } - - open override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool { - return .vertical == scrollDirection ? newBounds.width != collectionView!.bounds.width : newBounds.height != collectionView!.bounds.height - } - - open override func prepare() { - guard let dataSource = collectionView?.dataSource as? CollectionViewDataSource else { - return - } +} + +extension CollectionViewLayout { + /** + Retrieves the index paths for the items within the passed in CGRect. + - Parameter rect: A CGRect that acts as the bounds to find the items within. + - Returns: An Array of NSIndexPath objects. + */ + public func indexPathsOfItems(in rect: CGRect) -> [NSIndexPath] { + var paths = [NSIndexPath]() - prepareLayoutForItems(dataSourceItems: dataSource.dataSourceItems) - } - - open override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint) -> CGPoint { - return proposedContentOffset - } - - fileprivate func prepareLayoutForItems(dataSourceItems: [DataSourceItem]) { - self.dataSourceItems = dataSourceItems - layoutItems.removeAll() - - offset.x = contentEdgeInsets.left - offset.y = contentEdgeInsets.top - - for i in 0.. UICollectionViewLayoutAttributes? { + let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath) + let dataSourceItem = dataSourceItems![indexPath.item] + + if 0 < itemSize.width && 0 < itemSize.height { + attributes.frame = CGRect(x: offset.x, y: offset.y, width: itemSize.width - contentEdgeInsets.left - contentEdgeInsets.right, height: itemSize.height - contentEdgeInsets.top - contentEdgeInsets.bottom) + } else if .vertical == scrollDirection { + if let h = dataSourceItem.height { + attributes.frame = CGRect(x: contentEdgeInsets.left, y: offset.y, width: collectionView!.bounds.width - contentEdgeInsets.left - contentEdgeInsets.right, height: h) + + } else if let v = dataSourceItem.data as? UIView, 0 < v.bounds.height { + v.updateConstraints() + v.setNeedsLayout() + v.layoutIfNeeded() + + attributes.frame = CGRect(x: contentEdgeInsets.left, y: offset.y, width: collectionView!.bounds.width - contentEdgeInsets.left - contentEdgeInsets.right, height: v.bounds.height) + + } else { + attributes.frame = CGRect(x: contentEdgeInsets.left, y: offset.y, width: collectionView!.bounds.width - contentEdgeInsets.left - contentEdgeInsets.right, height: collectionView!.bounds.height) + } + } else { + if let w = dataSourceItem.width { + attributes.frame = CGRect(x: offset.x, y: contentEdgeInsets.top, width: w, height: collectionView!.bounds.height - contentEdgeInsets.top - contentEdgeInsets.bottom) + + } else if let v = dataSourceItem.data as? UIView, 0 < v.bounds.width { + v.updateConstraints() + v.setNeedsLayout() + v.layoutIfNeeded() + + attributes.frame = CGRect(x: offset.x, y: contentEdgeInsets.top, width: v.bounds.width, height: collectionView!.bounds.height - contentEdgeInsets.top - contentEdgeInsets.bottom) + + } else { + attributes.frame = CGRect(x: offset.x, y: contentEdgeInsets.top, width: collectionView!.bounds.width, height: collectionView!.bounds.height - contentEdgeInsets.top - contentEdgeInsets.bottom) + } + } + + return attributes + } + + open override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? { + var layoutAttributes = [UICollectionViewLayoutAttributes]() + for (attribute, _) in layoutItems { + if rect.intersects(attribute.frame) { + layoutAttributes.append(attribute) + } + } + return layoutAttributes + } + + open override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool { + return .vertical == scrollDirection ? newBounds.width != collectionView!.bounds.width : newBounds.height != collectionView!.bounds.height + } + + open override func prepare() { + guard let dataSource = collectionView?.dataSource as? CollectionViewDataSource else { + return + } + + prepareLayout(for: dataSource.dataSourceItems) + } + + open override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint) -> CGPoint { + return proposedContentOffset + } } diff --git a/Example/Pods/Material/Sources/iOS/Color.swift b/Example/Pods/Material/Sources/iOS/Color.swift index d55a97f..a2183ff 100644 --- a/Example/Pods/Material/Sources/iOS/Color.swift +++ b/Example/Pods/Material/Sources/iOS/Color.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/Example/Pods/Material/Sources/iOS/CornerRadius.swift b/Example/Pods/Material/Sources/iOS/CornerRadius.swift index 9c0f98f..deaa93c 100644 --- a/Example/Pods/Material/Sources/iOS/CornerRadius.swift +++ b/Example/Pods/Material/Sources/iOS/CornerRadius.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/Example/Pods/Material/Sources/iOS/DataSourceItem.swift b/Example/Pods/Material/Sources/iOS/DataSourceItem.swift index edfd646..88f051c 100644 --- a/Example/Pods/Material/Sources/iOS/DataSourceItem.swift +++ b/Example/Pods/Material/Sources/iOS/DataSourceItem.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/Example/Pods/Material/Sources/iOS/Depth.swift b/Example/Pods/Material/Sources/iOS/Depth.swift index 07fa200..a38f67c 100644 --- a/Example/Pods/Material/Sources/iOS/Depth.swift +++ b/Example/Pods/Material/Sources/iOS/Depth.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -50,6 +50,11 @@ public struct Depth { /// Radius. public var radius: CGFloat + /// A tuple of raw values. + public var rawValue: (CGSize, Float, CGFloat) { + return (offset.asSize, opacity, radius) + } + /// Preset. public var preset = DepthPreset.none { didSet { @@ -62,9 +67,9 @@ public struct Depth { /** Initializer that takes in an offset, opacity, and radius. - - Parameter offset: UIOffset. - - Parameter opacity: Float. - - Parameter radius: CGFloat. + - Parameter offset: A UIOffset. + - Parameter opacity: A Float. + - Parameter radius: A CGFloat. */ public init(offset: Offset = .zero, opacity: Float = 0, radius: CGFloat = 0) { self.offset = offset diff --git a/Example/Pods/Material/Sources/iOS/Device.swift b/Example/Pods/Material/Sources/iOS/Device.swift index 472e0ed..b4f9dde 100644 --- a/Example/Pods/Material/Sources/iOS/Device.swift +++ b/Example/Pods/Material/Sources/iOS/Device.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,7 +30,8 @@ import UIKit -public enum DeviceModel { +@objc(DeviceModel) +public enum DeviceModel: Int { case iPodTouch5 case iPodTouch6 case iPhone4 @@ -116,3 +117,13 @@ public struct Device { return UIDevice.current.userInterfaceIdiom } } + + +public func ==(lhs: DeviceModel, rhs: DeviceModel) -> Bool { + return lhs.rawValue == rhs.rawValue +} + +public func !=(lhs: DeviceModel, rhs: DeviceModel) -> Bool { + return lhs.rawValue != rhs.rawValue +} + diff --git a/Example/Pods/Material/Sources/iOS/Display.swift b/Example/Pods/Material/Sources/iOS/DisplayStyle.swift similarity index 93% rename from Example/Pods/Material/Sources/iOS/Display.swift rename to Example/Pods/Material/Sources/iOS/DisplayStyle.swift index 77b67c1..cc601a4 100644 --- a/Example/Pods/Material/Sources/iOS/Display.swift +++ b/Example/Pods/Material/Sources/iOS/DisplayStyle.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,8 +30,8 @@ import UIKit -@objc(Display) -public enum Display: Int { +@objc(DisplayStyle) +public enum DisplayStyle: Int { case partial case full } diff --git a/Example/Pods/Material/Sources/iOS/Divider.swift b/Example/Pods/Material/Sources/iOS/Divider.swift index 05a2ec3..73e70ca 100644 --- a/Example/Pods/Material/Sources/iOS/Divider.swift +++ b/Example/Pods/Material/Sources/iOS/Divider.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -135,18 +135,18 @@ public struct Divider { } /// A memory reference to the Divider instance. -private var DividerKey: UInt8 = 0 +fileprivate var DividerKey: UInt8 = 0 extension UIView { /// TabBarItem reference. public private(set) var divider: Divider { get { - return AssociatedObject(base: self, key: &DividerKey) { + return AssociatedObject.get(base: self, key: &DividerKey) { return Divider(view: self) } } set(value) { - AssociateObject(base: self, key: &DividerKey, value: value) + AssociatedObject.set(base: self, key: &DividerKey, value: value) } } @@ -212,4 +212,9 @@ extension UIView { divider.thickness = value } } + + /// Sets the divider frame. + open func layoutDivider() { + divider.reload() + } } diff --git a/Example/Pods/Material/Sources/iOS/DynamicFontType.swift b/Example/Pods/Material/Sources/iOS/DynamicFontType.swift index 3a2aa5f..90a4f1a 100644 --- a/Example/Pods/Material/Sources/iOS/DynamicFontType.swift +++ b/Example/Pods/Material/Sources/iOS/DynamicFontType.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -63,6 +63,6 @@ open class DynamicFontType: NSObject { /// Prepares observation for content size changes. private func prepareContentSizeObservation() { - NotificationCenter.default.addObserver(self, selector: #selector(handleContentSizeChange), name: NSNotification.Name.UIContentSizeCategoryDidChange, object: nil) + NotificationCenter.default.addObserver(self, selector: #selector(handleContentSizeChange), name: .UIContentSizeCategoryDidChange, object: nil) } } diff --git a/Example/Pods/Material/Sources/iOS/EdgeInsets.swift b/Example/Pods/Material/Sources/iOS/EdgeInsets.swift index d5c1336..e21d21f 100644 --- a/Example/Pods/Material/Sources/iOS/EdgeInsets.swift +++ b/Example/Pods/Material/Sources/iOS/EdgeInsets.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -44,6 +44,12 @@ public enum EdgeInsetsPreset: Int { case square7 case square8 case square9 + case square10 + case square11 + case square12 + case square13 + case square14 + case square15 // rectangle case wideRectangle1 @@ -66,6 +72,20 @@ public enum EdgeInsetsPreset: Int { case tallRectangle7 case tallRectangle8 case tallRectangle9 + + /// horizontally + case horizontally1 + case horizontally2 + case horizontally3 + case horizontally4 + case horizontally5 + + /// vertically + case vertically1 + case vertically2 + case vertically3 + case vertically4 + case vertically5 } public typealias EdgeInsets = UIEdgeInsets @@ -84,16 +104,28 @@ public func EdgeInsetsPresetToValue(preset: EdgeInsetsPreset) -> EdgeInsets { case .square3: return EdgeInsets(top: 16, left: 16, bottom: 16, right: 16) case .square4: - return EdgeInsets(top: 24, left: 24, bottom: 24, right: 24) + return EdgeInsets(top: 20, left: 20, bottom: 20, right: 20) case .square5: - return EdgeInsets(top: 32, left: 32, bottom: 32, right: 32) + return EdgeInsets(top: 24, left: 24, bottom: 24, right: 24) case .square6: - return EdgeInsets(top: 40, left: 40, bottom: 40, right: 40) + return EdgeInsets(top: 28, left: 28, bottom: 28, right: 28) case .square7: - return EdgeInsets(top: 48, left: 48, bottom: 48, right: 48) + return EdgeInsets(top: 32, left: 32, bottom: 32, right: 32) case .square8: - return EdgeInsets(top: 56, left: 56, bottom: 56, right: 56) + return EdgeInsets(top: 36, left: 36, bottom: 36, right: 36) case .square9: + return EdgeInsets(top: 40, left: 40, bottom: 40, right: 40) + case .square10: + return EdgeInsets(top: 44, left: 44, bottom: 44, right: 44) + case .square11: + return EdgeInsets(top: 48, left: 48, bottom: 48, right: 48) + case .square12: + return EdgeInsets(top: 52, left: 52, bottom: 52, right: 52) + case .square13: + return EdgeInsets(top: 56, left: 56, bottom: 56, right: 56) + case .square14: + return EdgeInsets(top: 60, left: 60, bottom: 60, right: 60) + case .square15: return EdgeInsets(top: 64, left: 64, bottom: 64, right: 64) // rectangle @@ -135,5 +167,29 @@ public func EdgeInsetsPresetToValue(preset: EdgeInsetsPreset) -> EdgeInsets { return EdgeInsets(top: 56, left: 28, bottom: 56, right: 28) case .tallRectangle9: return EdgeInsets(top: 64, left: 32, bottom: 64, right: 32) + + /// horizontally + case .horizontally1: + return EdgeInsets(top: 0, left: 2, bottom: 0, right: 2) + case .horizontally2: + return EdgeInsets(top: 0, left: 4, bottom: 0, right: 4) + case .horizontally3: + return EdgeInsets(top: 0, left: 8, bottom: 0, right: 8) + case .horizontally4: + return EdgeInsets(top: 0, left: 16, bottom: 0, right: 16) + case .horizontally5: + return EdgeInsets(top: 0, left: 24, bottom: 0, right: 24) + + /// vertically + case .vertically1: + return EdgeInsets(top: 2, left: 0, bottom: 2, right: 0) + case .vertically2: + return EdgeInsets(top: 4, left: 0, bottom: 4, right: 0) + case .vertically3: + return EdgeInsets(top: 8, left: 0, bottom: 8, right: 0) + case .vertically4: + return EdgeInsets(top: 16, left: 0, bottom: 16, right: 0) + case .vertically5: + return EdgeInsets(top: 24, left: 0, bottom: 24, right: 0) } } diff --git a/Example/Pods/Material/Sources/iOS/Editor.swift b/Example/Pods/Material/Sources/iOS/Editor.swift deleted file mode 100644 index 1b32653..0000000 --- a/Example/Pods/Material/Sources/iOS/Editor.swift +++ /dev/null @@ -1,381 +0,0 @@ -/* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, 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 of CosmicMind 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. - */ - -import UIKit - -@objc(EditorDelegate) -public protocol EditorDelegate { - /** - A delegation method that is executed when text will be - processed during editing. - - Parameter editor: An Editor. - - Parameter willProcessEditing textStorage: A TextStorage. - - Parameter text: A String. - - Parameter range: A NSRange. - */ - @objc - optional func editor(editor: Editor, willProcessEditing textStorage: TextStorage, text: String, range: NSRange) - - /** - A delegation method that is executed when text has been - processed after editing. - - Parameter editor: An Editor. - - Parameter didProcessEditing textStorage: A TextStorage. - - Parameter text: A String. - - Parameter range: A NSRange. - */ - @objc - optional func editor(editor: Editor, didProcessEditing textStorage: TextStorage, text: String, range: NSRange) - - /** - A delegation method that is executed when the textView should begin editing. - - Parameter editor: An Editor. - - Parameter shouldBeginEditing textView: A UITextView. - - Returns: A boolean indicating if the textView should begin editing, true if - yes, false otherwise. - */ - @objc - optional func editor(editor: Editor, shouldBeginEditing textView: UITextView) -> Bool - - /** - A delegation method that is executed when the textView should end editing. - - Parameter editor: An Editor. - - Parameter shouldEndEditing textView: A UITextView. - - Returns: A boolean indicating if the textView should end editing, true if - yes, false otherwise. - */ - @objc - optional func editor(editor: Editor, shouldEndEditing textView: UITextView) -> Bool - - /** - A delegation method that is executed when the textView did begin editing. - - Parameter editor: An Editor. - - Parameter didBeginEditing textView: A UITextView. - */ - @objc - optional func editor(editor: Editor, didBeginEditing textView: UITextView) - - /** - A delegation method that is executed when the textView did begin editing. - - Parameter editor: An Editor. - - Parameter didBeginEditing textView: A UITextView. - */ - @objc - optional func editor(editor: Editor, didEndEditing textView: UITextView) - - /** - A delegation method that is executed when the textView should change text in - a given range with replacement text. - - Parameter editor: An Editor. - - Parameter textView: A UITextView. - - Parameter shouldChangeTextIn range: A NSRange. - - Parameter replacementText text: A String. - - Returns: A boolean indicating if the textView should change text in a given - range with the given replacement text, true if yes, false otherwise. - */ - @objc - optional func editor(editor: Editor, textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool - - /** - A delegation method that is executed when the textView did change. - - Parameter editor: An Editor. - - Parameter didChange textView: A UITextView. - */ - @objc - optional func editor(editor: Editor, didChange textView: UITextView) - - /** - A delegation method that is executed when the textView did change a selection. - - Parameter editor: An Editor. - - Parameter didChangeSelection textView: A UITextView. - */ - @objc - optional func editor(editor: Editor, didChangeSelection textView: UITextView) - - /** - A delegation method that is executed when the textView should interact with - a URL in a given character range. - - Parameter editor: An Editor. - - Parameter textView: A UITextView. - - Parameter shouldInteractWith URL: A URL. - - Parameter in characterRange: A Range. - - Returns: A boolean indicating if the textView should interact with a URL in - a given character range, true if yes, false otherwise. - - @available(iOS, introduced: 8.0, deprecated: 10.0) - @objc - optional func editor(editor: Editor, textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange) -> Bool - - A delegation method that is executed when the textView should interact with - a text attachment in a given character range. - - Parameter editor: An Editor. - - Parameter textView: A UITextView. - - Parameter shouldInteractWith textAttachment: A NSTextAttachment. - - Parameter in characterRange: A Range. - - Returns: A boolean indicating if the textView should interact with a - NSTextAttachment in a given character range, true if yes, false otherwise. - @available(iOS, introduced: 8.0, deprecated: 10.0) - @objc - optional func editor(editor: Editor, textView: UITextView, shouldInteractWith textAttachment: NSTextAttachment, in characterRange: NSRange) -> Bool - - A delegation method that is executed when the textView should interact with - a URL in a given character range. - - Parameter editor: An Editor. - - Parameter textView: A UITextView. - - Parameter shouldInteractWith URL: A URL. - - Parameter in characterRange: A Range. - - Parameter interaction: A UITextItemInteraction. - - Returns: A boolean indicating if the textView should interact with a URL in - a given character range, true if yes, false otherwise. - @available(iOS 10.0, *) - @objc - optional func editor(editor: Editor, textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool - - A delegation method that is executed when the textView should interact with - a text attachment in a given character range. - - Parameter editor: An Editor. - - Parameter textView: A UITextView. - - Parameter shouldInteractWith textAttachment: A NSTextAttachment. - - Parameter in characterRange: A Range. - - Parameter interaction: A UITextItemInteraction. - - Returns: A boolean indicating if the textView should interact with a - NSTextAttachment in a given character range, true if yes, false otherwise. - @available(iOS 10.0, *) - @objc - optional func editor(editor: Editor, textView: UITextView, shouldInteractWith textAttachment: NSTextAttachment, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool - */ -} - -open class Editor: View { - /// Will layout the view. - open var willLayout: Bool { - return 0 < width && 0 < height && nil != superview - } - - /// TextStorage instance that is observed while editing. - open fileprivate(set) var textStorage: TextStorage! - - /// A reference to the NSTextContainer. - open fileprivate(set) var textContainer: NSTextContainer! - - /// A reference to the NSLayoutManager. - open fileprivate(set) var layoutManager: NSLayoutManager! - - /// A preset wrapper around textViewEdgeInsets. - open var textViewEdgeInsetsPreset = EdgeInsetsPreset.none { - didSet { - textViewEdgeInsets = EdgeInsetsPresetToValue(preset: textViewEdgeInsetsPreset) - } - } - - /// A reference to textViewEdgeInsets. - @IBInspectable - open var textViewEdgeInsets = EdgeInsets.zero { - didSet { - layoutSubviews() - } - } - - /// Reference to the TextView. - open fileprivate(set) var textView: UITextView! - - /// A reference to an EditorDelegate. - open weak var delegate: EditorDelegate? - - /// The string pattern to match within the textStorage. - open var pattern = "(^|\\s)#[\\d\\w_\u{203C}\u{2049}\u{20E3}\u{2122}\u{2139}\u{2194}-\u{2199}\u{21A9}-\u{21AA}\u{231A}-\u{231B}\u{23E9}-\u{23EC}\u{23F0}\u{23F3}\u{24C2}\u{25AA}-\u{25AB}\u{25B6}\u{25C0}\u{25FB}-\u{25FE}\u{2600}-\u{2601}\u{260E}\u{2611}\u{2614}-\u{2615}\u{261D}\u{263A}\u{2648}-\u{2653}\u{2660}\u{2663}\u{2665}-\u{2666}\u{2668}\u{267B}\u{267F}\u{2693}\u{26A0}-\u{26A1}\u{26AA}-\u{26AB}\u{26BD}-\u{26BE}\u{26C4}-\u{26C5}\u{26CE}\u{26D4}\u{26EA}\u{26F2}-\u{26F3}\u{26F5}\u{26FA}\u{26FD}\u{2702}\u{2705}\u{2708}-\u{270C}\u{270F}\u{2712}\u{2714}\u{2716}\u{2728}\u{2733}-\u{2734}\u{2744}\u{2747}\u{274C}\u{274E}\u{2753}-\u{2755}\u{2757}\u{2764}\u{2795}-\u{2797}\u{27A1}\u{27B0}\u{2934}-\u{2935}\u{2B05}-\u{2B07}\u{2B1B}-\u{2B1C}\u{2B50}\u{2B55}\u{3030}\u{303D}\u{3297}\u{3299}\u{1F004}\u{1F0CF}\u{1F170}-\u{1F171}\u{1F17E}-\u{1F17F}\u{1F18E}\u{1F191}-\u{1F19A}\u{1F1E7}-\u{1F1EC}\u{1F1EE}-\u{1F1F0}\u{1F1F3}\u{1F1F5}\u{1F1F7}-\u{1F1FA}\u{1F201}-\u{1F202}\u{1F21A}\u{1F22F}\u{1F232}-\u{1F23A}\u{1F250}-\u{1F251}\u{1F300}-\u{1F320}\u{1F330}-\u{1F335}\u{1F337}-\u{1F37C}\u{1F380}-\u{1F393}\u{1F3A0}-\u{1F3C4}\u{1F3C6}-\u{1F3CA}\u{1F3E0}-\u{1F3F0}\u{1F400}-\u{1F43E}\u{1F440}\u{1F442}-\u{1F4F7}\u{1F4F9}-\u{1F4FC}\u{1F500}-\u{1F507}\u{1F509}-\u{1F53D}\u{1F550}-\u{1F567}\u{1F5FB}-\u{1F640}\u{1F645}-\u{1F64F}\u{1F680}-\u{1F68A}]+" { - didSet { - prepareRegularExpression() - } - } - - /** - A convenience property that accesses the textStorage - string. - */ - open var string: String { - return textStorage.string - } - - /// An Array of matches that match the pattern expression. - open var matches: [String] { - return textStorage.expression!.matches(in: string, options: [], range: NSMakeRange(0, string.utf16.count)).map { [unowned self] in - (self.string as NSString).substring(with: $0.range).trimmed - } - } - - /** - An Array of unique matches that match the pattern - expression. - */ - public var uniqueMatches: [String] { - var seen = [String: Bool]() - return matches.filter { nil == seen.updateValue(true, forKey: $0) } - } - - open override func layoutSubviews() { - super.layoutSubviews() - guard willLayout else { - return - } - - textView.frame = CGRect(x: textViewEdgeInsets.left, y: textViewEdgeInsets.top, width: width - textViewEdgeInsets.left - textViewEdgeInsets.right, height: height - textViewEdgeInsets.top - textViewEdgeInsets.bottom) - } - - /** - Prepares the view instance when intialized. When subclassing, - it is recommended to override the prepare method - to initialize property values and other setup operations. - The super.prepare method should always be called immediately - when subclassing. - */ - open override func prepare() { - super.prepare() - prepareTextContainer() - prepareLayoutManager() - prepareTextStorage() - prepareRegularExpression() - prepareTextView() - } -} - -extension Editor { - /// Prepares the textContainer. - fileprivate func prepareTextContainer() { - textContainer = NSTextContainer(size: bounds.size) - } - - /// Prepares the layoutManager. - fileprivate func prepareLayoutManager() { - layoutManager = NSLayoutManager() - layoutManager.addTextContainer(textContainer) - } - - /// Prepares the textStorage. - fileprivate func prepareTextStorage() { - textStorage = TextStorage() - textStorage.addLayoutManager(layoutManager) - textStorage.delegate = self - } - - /// Prepares the textView. - fileprivate func prepareTextView() { - textView = UITextView(frame: .zero, textContainer: textContainer) - textView.delegate = self - addSubview(textView) - } - - /// Prepares the regular expression for matching. - fileprivate func prepareRegularExpression() { - textStorage.expression = try? NSRegularExpression(pattern: pattern, options: []) - } -} - -extension Editor: TextStorageDelegate { - @objc - open func textStorage(textStorage: TextStorage, willProcessEditing text: String, range: NSRange) { - delegate?.editor?(editor: self, willProcessEditing: textStorage, text: string, range: range) - } - - @objc - open func textStorage(textStorage: TextStorage, didProcessEditing text: String, result: NSTextCheckingResult?, flags: NSRegularExpression.MatchingFlags, stop: UnsafeMutablePointer) { - guard let range = result?.range else { - return - } - - delegate?.editor?(editor: self, didProcessEditing: textStorage, text: string, range: range) - } -} - -extension Editor: UITextViewDelegate { - @objc - open func textViewShouldBeginEditing(_ textView: UITextView) -> Bool { - return delegate?.editor?(editor: self, shouldBeginEditing: textView) ?? true - } - - @objc - open func textViewShouldEndEditing(_ textView: UITextView) -> Bool { - return delegate?.editor?(editor: self, shouldEndEditing: textView) ?? true - } - - @objc - open func textViewDidBeginEditing(_ textView: UITextView) { - delegate?.editor?(editor: self, didBeginEditing: textView) - } - - @objc - open func textViewDidEndEditing(_ textView: UITextView) { - delegate?.editor?(editor: self, didEndEditing: textView) - } - - @objc - open func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool { - return delegate?.editor?(editor: self, textView: textView, shouldChangeTextIn: range, replacementText: text) ?? true - } - - @objc - open func textViewDidChange(_ textView: UITextView) { - delegate?.editor?(editor: self, didChange: textView) - } - - @objc - open func textViewDidChangeSelection(_ textView: UITextView) { - delegate?.editor?(editor: self, didChangeSelection: textView) - } -} - -/* -@available(iOS, introduced: 8.0, deprecated: : 10.0) -extension Editor { - @objc - open func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange) -> Bool { - return delegate?.editor?(editor: self, textView: textView, shouldInteractWith: URL, in: characterRange) ?? true - } - - @objc - open func textView(_ textView: UITextView, shouldInteractWith textAttachment: NSTextAttachment, in characterRange: NSRange) -> Bool { - return delegate?.editor?(editor: self, textView: textView, shouldInteractWith: textAttachment, in: characterRange) ?? true - } -} - -@available(iOS 10.0, *) -extension Editor { - - @objc - open func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool { - return delegate?.editor?(editor: self, textView: textView, shouldInteractWith: URL, in: characterRange, interaction: interaction) ?? true - } - - @objc - open func textView(_ textView: UITextView, shouldInteractWith textAttachment: NSTextAttachment, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool { - return delegate?.editor?(editor: self, textView: textView, shouldInteractWith: textAttachment, in: characterRange, interaction: interaction) ?? true - } -} -*/ diff --git a/Example/Pods/Material/Sources/iOS/ErrorTextField.swift b/Example/Pods/Material/Sources/iOS/ErrorTextField.swift index a2c83b0..91868e1 100644 --- a/Example/Pods/Material/Sources/iOS/ErrorTextField.swift +++ b/Example/Pods/Material/Sources/iOS/ErrorTextField.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -40,13 +40,6 @@ open class ErrorTextField: TextField { } } - /** - Prepares the view instance when intialized. When subclassing, - it is recommended to override the prepare method - to initialize property values and other setup operations. - The super.prepare method should always be called immediately - when subclassing. - */ open override func prepare() { super.prepare() isErrorRevealed = false diff --git a/Example/Pods/Material/Sources/iOS/FABMenu.swift b/Example/Pods/Material/Sources/iOS/FABMenu.swift new file mode 100644 index 0000000..df638f7 --- /dev/null +++ b/Example/Pods/Material/Sources/iOS/FABMenu.swift @@ -0,0 +1,473 @@ +/* + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, 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 of CosmicMind 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. + */ + +import UIKit + +@objc(FABMenuItemTitleLabelPosition) +public enum FABMenuItemTitleLabelPosition: Int { + case left + case right +} + +@objc(FABMenuDirection) +public enum FABMenuDirection: Int { + case up + case down + case left + case right +} + +open class FABMenuItem: View { + /// A reference to the titleLabel. + open let titleLabel = UILabel() + + /// The titleLabel side. + open var titleLabelPosition = FABMenuItemTitleLabelPosition.left + + /// A reference to the fabButton. + open let fabButton = FABButton() + + open override func prepare() { + super.prepare() + backgroundColor = nil + + prepareFABButton() + prepareTitleLabel() + } + + /// A reference to the titleLabel text. + open var title: String? { + get { + return titleLabel.text + } + set(value) { + titleLabel.text = value + layoutSubviews() + } + } + + open override func layoutSubviews() { + super.layoutSubviews() + guard let t = title, 0 < t.utf16.count else { + titleLabel.removeFromSuperview() + return + } + + if nil == titleLabel.superview { + addSubview(titleLabel) + } + } +} + +extension FABMenuItem { + /// Shows the titleLabel. + open func showTitleLabel() { + let interimSpace = InterimSpacePresetToValue(preset: .interimSpace6) + + titleLabel.sizeToFit() + titleLabel.width += 1.5 * interimSpace + titleLabel.height += interimSpace / 2 + titleLabel.y = (height - titleLabel.height) / 2 + + switch titleLabelPosition { + case .left: + titleLabel.x = -titleLabel.width - interimSpace + case .right: + titleLabel.x = frame.width + interimSpace + } + + titleLabel.alpha = 0 + titleLabel.isHidden = false + + UIView.animate(withDuration: 0.25, animations: { [weak self] in + guard let s = self else { + return + } + + s.titleLabel.alpha = 1 + }) + } + + /// Hides the titleLabel. + open func hideTitleLabel() { + titleLabel.isHidden = true + } +} + +extension FABMenuItem { + /// Prepares the fabButton. + fileprivate func prepareFABButton() { + layout(fabButton).edges() + } + + /// Prepares the titleLabel. + fileprivate func prepareTitleLabel() { + titleLabel.font = RobotoFont.regular(with: 14) + titleLabel.textAlignment = .center + titleLabel.backgroundColor = .white + titleLabel.depthPreset = fabButton.depthPreset + titleLabel.cornerRadiusPreset = .cornerRadius1 + } +} + +@objc(FABMenuDelegate) +public protocol FABMenuDelegate { + /** + A delegation method that is execited when the fabMenu will open. + - Parameter fabMenu: A FABMenu. + */ + @objc + optional func fabMenuWillOpen(fabMenu: FABMenu) + + /** + A delegation method that is execited when the fabMenu did open. + - Parameter fabMenu: A FABMenu. + */ + @objc + optional func fabMenuDidOpen(fabMenu: FABMenu) + + /** + A delegation method that is execited when the fabMenu will close. + - Parameter fabMenu: A FABMenu. + */ + @objc + optional func fabMenuWillClose(fabMenu: FABMenu) + + /** + A delegation method that is execited when the fabMenu did close. + - Parameter fabMenu: A FABMenu. + */ + @objc + optional func fabMenuDidClose(fabMenu: FABMenu) + + /** + A delegation method that is executed when the user taps while + the menu is opened. + - Parameter fabMenu: A FABMenu. + - Parameter tappedAt point: A CGPoint. + - Parameter isOutside: A boolean indicating whether the tap + was outside the menu button area. + */ + @objc + optional func fabMenu(fabMenu: FABMenu, tappedAt point: CGPoint, isOutside: Bool) +} + +@objc(FABMenu) +open class FABMenu: View { + /// A reference to the SpringAnimation object. + internal let spring = SpringAnimation() + + open var fabMenuDirection: FABMenuDirection { + get { + switch spring.springDirection { + case .up: + return .up + case .down: + return .down + case .left: + return .left + case .right: + return .right + } + } + set(value) { + switch value { + case .up: + spring.springDirection = .up + case .down: + spring.springDirection = .down + case .left: + spring.springDirection = .left + case .right: + spring.springDirection = .right + } + + layoutSubviews() + } + } + + /// A reference to the base FABButton. + open var fabButton: FABButton? { + didSet { + oldValue?.removeFromSuperview() + + guard let v = fabButton else { + return + } + + addSubview(v) + v.addTarget(self, action: #selector(handleFABButton(button:)), for: .touchUpInside) + } + } + + /// An open handler for the FABButton. + open var handleFABButtonCallback: ((UIButton) -> Void)? + + /// An internal handler for the open function. + internal var handleOpenCallback: (() -> Void)? + + /// An internal handler for the close function. + internal var handleCloseCallback: (() -> Void)? + + /// An internal handler for the completion function. + internal var handleCompletionCallback: ((UIView) -> Void)? + + /// Size of FABMenuItems. + open var fabMenuItemSize: CGSize { + get { + return spring.itemSize + } + set(value) { + spring.itemSize = value + } + } + + /// A preset wrapper around interimSpace. + open var interimSpacePreset: InterimSpacePreset { + get { + return spring.interimSpacePreset + } + set(value) { + spring.interimSpacePreset = value + } + } + + /// The space between views. + open var interimSpace: InterimSpace { + get { + return spring.interimSpace + } + set(value) { + spring.interimSpace = value + } + } + + /// A boolean indicating if the menu is open or not. + open var isOpened: Bool { + get { + return spring.isOpened + } + set(value) { + spring.isOpened = value + } + } + + /// A boolean indicating if the menu is enabled. + open var isEnabled: Bool { + get { + return spring.isEnabled + } + set(value) { + spring.isEnabled = value + } + } + + /// An optional delegation handler. + open weak var delegate: FABMenuDelegate? + + /// A reference to the FABMenuItems + open var fabMenuItems: [FABMenuItem] { + get { + return spring.views as! [FABMenuItem] + } + set(value) { + for v in spring.views { + v.removeFromSuperview() + } + + for v in value { + addSubview(v) + } + + spring.views = value + } + } + + open override func layoutSubviews() { + super.layoutSubviews() + fabButton?.frame.size = bounds.size + spring.baseSize = bounds.size + } + + open override func prepare() { + super.prepare() + backgroundColor = nil + interimSpacePreset = .interimSpace6 + } +} + +extension FABMenu { + /** + Open the Menu component with animation options. + - Parameter duration: The time for each view's animation. + - Parameter delay: A delay time for each view's animation. + - Parameter usingSpringWithDamping: A damping ratio for the animation. + - Parameter initialSpringVelocity: The initial velocity for the animation. + - Parameter options: Options to pass to the animation. + - Parameter animations: An animation block to execute on each view's animation. + - Parameter completion: A completion block to execute on each view's animation. + */ + open func open(duration: TimeInterval = 0.15, delay: TimeInterval = 0, usingSpringWithDamping: CGFloat = 0.5, initialSpringVelocity: CGFloat = 0, options: UIViewAnimationOptions = [], animations: ((UIView) -> Void)? = nil, completion: ((UIView) -> Void)? = nil) { + open(isTriggeredByUserInteraction: false, duration: duration, delay: delay, usingSpringWithDamping: usingSpringWithDamping, initialSpringVelocity: initialSpringVelocity, options: options, animations: animations, completion: completion) + } + + /** + Open the Menu component with animation options. + - Parameter isTriggeredByUserInteraction: A boolean indicating whether the + state was changed by a user interaction, true if yes, false otherwise. + - Parameter duration: The time for each view's animation. + - Parameter delay: A delay time for each view's animation. + - Parameter usingSpringWithDamping: A damping ratio for the animation. + - Parameter initialSpringVelocity: The initial velocity for the animation. + - Parameter options: Options to pass to the animation. + - Parameter animations: An animation block to execute on each view's animation. + - Parameter completion: A completion block to execute on each view's animation. + */ + open func open(isTriggeredByUserInteraction: Bool, duration: TimeInterval = 0.15, delay: TimeInterval = 0, usingSpringWithDamping: CGFloat = 0.5, initialSpringVelocity: CGFloat = 0, options: UIViewAnimationOptions = [], animations: ((UIView) -> Void)? = nil, completion: ((UIView) -> Void)? = nil) { + handleOpenCallback?() + + if isTriggeredByUserInteraction { + delegate?.fabMenuWillOpen?(fabMenu: self) + } + + spring.expand(duration: duration, delay: delay, usingSpringWithDamping: usingSpringWithDamping, initialSpringVelocity: initialSpringVelocity, options: options, animations: animations) { [weak self, isTriggeredByUserInteraction = isTriggeredByUserInteraction, completion = completion] (view) in + guard let s = self else { + return + } + + (view as? FABMenuItem)?.showTitleLabel() + + if isTriggeredByUserInteraction && view == s.fabMenuItems.last { + s.delegate?.fabMenuDidOpen?(fabMenu: s) + } + + completion?(view) + s.handleCompletionCallback?(view) + } + } + + /** + Close the Menu component with animation options. + - Parameter duration: The time for each view's animation. + - Parameter delay: A delay time for each view's animation. + - Parameter usingSpringWithDamping: A damping ratio for the animation. + - Parameter initialSpringVelocity: The initial velocity for the animation. + - Parameter options: Options to pass to the animation. + - Parameter animations: An animation block to execute on each view's animation. + - Parameter completion: A completion block to execute on each view's animation. + */ + open func close(duration: TimeInterval = 0.15, delay: TimeInterval = 0, usingSpringWithDamping: CGFloat = 0.5, initialSpringVelocity: CGFloat = 0, options: UIViewAnimationOptions = [], animations: ((UIView) -> Void)? = nil, completion: ((UIView) -> Void)? = nil) { + close(isTriggeredByUserInteraction: false, duration: duration, delay: delay, usingSpringWithDamping: usingSpringWithDamping, initialSpringVelocity: initialSpringVelocity, options: options, animations: animations, completion: completion) + } + + /** + Close the Menu component with animation options. + - Parameter isTriggeredByUserInteraction: A boolean indicating whether the + state was changed by a user interaction, true if yes, false otherwise. + - Parameter duration: The time for each view's animation. + - Parameter delay: A delay time for each view's animation. + - Parameter usingSpringWithDamping: A damping ratio for the animation. + - Parameter initialSpringVelocity: The initial velocity for the animation. + - Parameter options: Options to pass to the animation. + - Parameter animations: An animation block to execute on each view's animation. + - Parameter completion: A completion block to execute on each view's animation. + */ + open func close(isTriggeredByUserInteraction: Bool, duration: TimeInterval = 0.15, delay: TimeInterval = 0, usingSpringWithDamping: CGFloat = 0.5, initialSpringVelocity: CGFloat = 0, options: UIViewAnimationOptions = [], animations: ((UIView) -> Void)? = nil, completion: ((UIView) -> Void)? = nil) { + handleCloseCallback?() + + if isTriggeredByUserInteraction { + delegate?.fabMenuWillClose?(fabMenu: self) + } + + spring.contract(duration: duration, delay: delay, usingSpringWithDamping: usingSpringWithDamping, initialSpringVelocity: initialSpringVelocity, options: options, animations: animations) { [weak self, isTriggeredByUserInteraction = isTriggeredByUserInteraction, completion = completion] (view) in + guard let s = self else { + return + } + + (view as? FABMenuItem)?.hideTitleLabel() + + if isTriggeredByUserInteraction && view == s.fabMenuItems.last { + s.delegate?.fabMenuDidClose?(fabMenu: s) + } + + completion?(view) + s.handleCompletionCallback?(view) + } + } +} + +extension FABMenu { + /** + Handles the hit test for the Menu and views outside of the Menu bounds. + - Parameter _ point: A CGPoint. + - Parameter with event: An optional UIEvent. + - Returns: An optional UIView. + */ + open override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { + guard isOpened, isEnabled else { + return super.hitTest(point, with: event) + } + + for v in subviews { + let p = v.convert(point, from: self) + if v.bounds.contains(p) { + delegate?.fabMenu?(fabMenu: self, tappedAt: point, isOutside: false) + return v.hitTest(p, with: event) + } + } + + delegate?.fabMenu?(fabMenu: self, tappedAt: point, isOutside: true) + + close(isTriggeredByUserInteraction: true) + + return super.hitTest(point, with: event) + } +} + +extension FABMenu { + /** + Handler to toggle the FABMenu opened or closed. + - Parameter button: A UIButton. + */ + @objc + fileprivate func handleFABButton(button: UIButton) { + guard nil == handleFABButtonCallback else { + handleFABButtonCallback?(button) + return + } + + guard isOpened else { + open(isTriggeredByUserInteraction: true) + return + } + + close(isTriggeredByUserInteraction: true) + } +} diff --git a/Example/Pods/Material/Sources/iOS/FABMenuController.swift b/Example/Pods/Material/Sources/iOS/FABMenuController.swift new file mode 100644 index 0000000..e655e76 --- /dev/null +++ b/Example/Pods/Material/Sources/iOS/FABMenuController.swift @@ -0,0 +1,217 @@ +/* + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, 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 of CosmicMind 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. + */ + +import UIKit + +public enum FABMenuBacking { + case none + case fade + case blur +} + +extension UIViewController { + /** + A convenience property that provides access to the FABMenuController. + This is the recommended method of accessing the FABMenuController + through child UIViewControllers. + */ + public var fabMenuController: FABMenuController? { + return traverseViewControllerHierarchyForClassType() + } +} + +open class FABMenuController: TransitionController { + /// Reference to the MenuView. + @IBInspectable + open let fabMenu = FABMenu() + + /// A FABMenuBacking value type. + open var fabMenuBacking = FABMenuBacking.blur + + /// The fabMenuBacking UIBlurEffectStyle. + open var fabMenuBackingBlurEffectStyle = UIBlurEffectStyle.light + + /// A reference to the blurView. + open fileprivate(set) var blurView: UIView? + + open override func layoutSubviews() { + super.layoutSubviews() + rootViewController.view.frame = view.bounds + } + + open override func prepare() { + super.prepare() + prepareFABMenu() + } +} + +extension FABMenuController: FABMenuDelegate {} + +extension FABMenuController { + /// Prepares the fabMenu. + fileprivate func prepareFABMenu() { + fabMenu.delegate = self + fabMenu.zPosition = 1000 + + fabMenu.handleFABButtonCallback = { [weak self] in + self?.handleFABButtonCallback(button: $0) + } + + fabMenu.handleOpenCallback = { [weak self] in + self?.handleOpenCallback() + } + + fabMenu.handleCloseCallback = { [weak self] in + self?.handleCloseCallback() + } + + fabMenu.handleCompletionCallback = { [weak self] in + self?.handleCompletionCallback(view: $0) + } + + view.addSubview(fabMenu) + } +} + +fileprivate extension FABMenuController { + /// Shows the fabMenuBacking. + func showFabMenuBacking() { + showFade() + showBlurView() + } + + /// Hides the fabMenuBacking. + func hideFabMenuBacking() { + hideFade() + hideBlurView() + } + + /// Shows the blurView. + func showBlurView() { + guard .blur == fabMenuBacking else { + return + } + + guard !fabMenu.isOpened, fabMenu.isEnabled else { + return + } + + guard nil == blurView else { + return + } + + let blur = UIVisualEffectView(effect: UIBlurEffect(style: fabMenuBackingBlurEffectStyle)) + blurView = UIView() + blurView?.layout(blur).edges() + view.layout(blurView!).edges() + view.bringSubview(toFront: fabMenu) + } + + /// Hides the blurView. + func hideBlurView() { + guard .blur == fabMenuBacking else { + return + } + + guard fabMenu.isOpened, fabMenu.isEnabled else { + return + } + + blurView?.removeFromSuperview() + blurView = nil + } + + /// Shows the fade. + func showFade() { + guard .fade == fabMenuBacking else { + return + } + + guard !fabMenu.isOpened, fabMenu.isEnabled else { + return + } + + UIView.animate(withDuration: 0.15, animations: { [weak self] in + self?.rootViewController.view.alpha = 0.15 + }) + } + + /// Hides the fade. + func hideFade() { + guard .fade == fabMenuBacking else { + return + } + + guard fabMenu.isOpened, fabMenu.isEnabled else { + return + } + + UIView.animate(withDuration: 0.15, animations: { [weak self] in + self?.rootViewController.view.alpha = 1 + }) + } +} + +fileprivate extension FABMenuController { + /** + Handler to toggle the FABMenu opened or closed. + - Parameter button: A UIButton. + */ + func handleFABButtonCallback(button: UIButton) { + guard fabMenu.isOpened else { + fabMenu.open(isTriggeredByUserInteraction: true) + return + } + + fabMenu.close(isTriggeredByUserInteraction: true) + } + + /// Handler for when the FABMenu.open function is called. + func handleOpenCallback() { + isUserInteractionEnabled = false + showFabMenuBacking() + } + + /// Handler for when the FABMenu.close function is called. + func handleCloseCallback() { + isUserInteractionEnabled = false + hideFabMenuBacking() + } + + /** + Completion handler for FABMenu open and close calls. + - Parameter view: A UIView. + */ + func handleCompletionCallback(view: UIView) { + if view == fabMenu.fabMenuItems.last { + isUserInteractionEnabled = true + } + } +} diff --git a/Example/Pods/Material/Sources/iOS/FabButton.swift b/Example/Pods/Material/Sources/iOS/FabButton.swift index 3ec59e8..e9ab9bf 100644 --- a/Example/Pods/Material/Sources/iOS/FabButton.swift +++ b/Example/Pods/Material/Sources/iOS/FabButton.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,14 +30,7 @@ import UIKit -open class FabButton: Button { - /** - Prepares the view instance when intialized. When subclassing, - it is recommended to override the prepare method - to initialize property values and other setup operations. - The super.prepare method should always be called immediately - when subclassing. - */ +open class FABButton: Button { open override func prepare() { super.prepare() depthPreset = .depth1 diff --git a/Example/Pods/Material/Sources/iOS/FlatButton.swift b/Example/Pods/Material/Sources/iOS/FlatButton.swift index 8bcea39..59f31dd 100644 --- a/Example/Pods/Material/Sources/iOS/FlatButton.swift +++ b/Example/Pods/Material/Sources/iOS/FlatButton.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,13 +31,6 @@ import UIKit open class FlatButton: Button { - /** - Prepares the view instance when intialized. When subclassing, - it is recommended to override the prepare method - to initialize property values and other setup operations. - The super.prepare method should always be called immediately - when subclassing. - */ open override func prepare() { super.prepare() cornerRadiusPreset = .cornerRadius1 diff --git a/Example/Pods/Material/Sources/iOS/Font.swift b/Example/Pods/Material/Sources/iOS/Font.swift index a5f1746..8f5c743 100644 --- a/Example/Pods/Material/Sources/iOS/Font.swift +++ b/Example/Pods/Material/Sources/iOS/Font.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -86,7 +86,7 @@ private class FontLoader { let bundle = Bundle(for: FontLoader.self) let identifier = bundle.bundleIdentifier - let fontURL = true == identifier?.hasPrefix("org.cocoapods") ? bundle.url(forResource: name, withExtension: "ttf", subdirectory: "io.cosmicmind.material.fonts.bundle") : bundle.url(forResource: name, withExtension: "ttf") + let fontURL = true == identifier?.hasPrefix("org.cocoapods") ? bundle.url(forResource: name, withExtension: "ttf", subdirectory: "com.cosmicmind.material.fonts.bundle") : bundle.url(forResource: name, withExtension: "ttf") if let v = fontURL { let data = NSData(contentsOf: v as URL)! @@ -97,7 +97,7 @@ private class FontLoader { if !CTFontManagerRegisterGraphicsFont(font, &error) { let errorDescription = CFErrorCopyDescription(error!.takeUnretainedValue()) let nsError = error!.takeUnretainedValue() as Any as! Error - NSException(name: .internalInconsistencyException, reason: errorDescription as? String, userInfo: [NSUnderlyingErrorKey: nsError as Any]).raise() + NSException(name: .internalInconsistencyException, reason: errorDescription as String?, userInfo: [NSUnderlyingErrorKey: nsError as Any]).raise() } } } diff --git a/Example/Pods/Material/Sources/iOS/Gravity.swift b/Example/Pods/Material/Sources/iOS/Gravity.swift index 7a93084..4d8459b 100644 --- a/Example/Pods/Material/Sources/iOS/Gravity.swift +++ b/Example/Pods/Material/Sources/iOS/Gravity.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/Example/Pods/Material/Sources/iOS/Grid.swift b/Example/Pods/Material/Sources/iOS/Grid.swift index 06f14d8..e1e3eff 100644 --- a/Example/Pods/Material/Sources/iOS/Grid.swift +++ b/Example/Pods/Material/Sources/iOS/Grid.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -266,19 +266,18 @@ public struct Grid { } /// A memory reference to the Grid instance for UIView extensions. -private var GridKey: UInt8 = 0 +fileprivate var GridKey: UInt8 = 0 -/// Grid extension for UIView. extension UIView { /// Grid reference. public var grid: Grid { get { - return AssociatedObject(base: self, key: &GridKey) { + return AssociatedObject.get(base: self, key: &GridKey) { return Grid(context: self) } } set(value) { - AssociateObject(base: self, key: &GridKey, value: value) + AssociatedObject.set(base: self, key: &GridKey, value: value) } } diff --git a/Example/Pods/Material/Sources/iOS/HeightPreset.swift b/Example/Pods/Material/Sources/iOS/HeightPreset.swift index 6b9ac97..6ab77a7 100644 --- a/Example/Pods/Material/Sources/iOS/HeightPreset.swift +++ b/Example/Pods/Material/Sources/iOS/HeightPreset.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -32,6 +32,7 @@ import UIKit @objc(HeightPreset) public enum HeightPreset: Int { + case none = 0 case tiny = 20 case xsmall = 28 case small = 36 diff --git a/Example/Pods/Material/Sources/iOS/Icon.swift b/Example/Pods/Material/Sources/iOS/Icon.swift index 4d2483b..b1c324a 100644 --- a/Example/Pods/Material/Sources/iOS/Icon.swift +++ b/Example/Pods/Material/Sources/iOS/Icon.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -42,7 +42,7 @@ public struct Icon { if nil == Icon.internalBundle { Icon.internalBundle = Bundle(for: View.self) let url = Icon.internalBundle!.resourceURL! - let b = Bundle(url: url.appendingPathComponent("io.cosmicmind.material.icons.bundle")) + let b = Bundle(url: url.appendingPathComponent("com.cosmicmind.material.icons.bundle")) if let v = b { Icon.internalBundle = v } diff --git a/Example/Pods/Material/Sources/iOS/IconButton.swift b/Example/Pods/Material/Sources/iOS/IconButton.swift index e094007..b4665d5 100644 --- a/Example/Pods/Material/Sources/iOS/IconButton.swift +++ b/Example/Pods/Material/Sources/iOS/IconButton.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,14 +31,7 @@ import UIKit open class IconButton: Button { - /** - Prepares the view instance when intialized. When subclassing, - it is recommended to override the prepare method - to initialize property values and other setup operations. - The super.prepare method should always be called immediately - when subclassing. - */ - open override func prepare() { + open override func prepare() { super.prepare() pulseAnimation = .center } diff --git a/Example/Pods/Material/Sources/iOS/ImageCard.swift b/Example/Pods/Material/Sources/iOS/ImageCard.swift index cde8b5c..0eb2e56 100644 --- a/Example/Pods/Material/Sources/iOS/ImageCard.swift +++ b/Example/Pods/Material/Sources/iOS/ImageCard.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,13 +30,18 @@ import UIKit -@objc(ToolbarAlignment) -public enum ToolbarAlignment: Int { - case top - case bottom -} - open class ImageCard: Card { + /** + A Display value to indicate whether or not to + display the imageView to the full view + bounds. + */ + open var displayStyle = DisplayStyle.partial { + didSet { + layoutSubviews() + } + } + /// A preset wrapper around imageViewEdgeInsets. open var imageViewEdgeInsetsPreset = EdgeInsetsPreset.none { didSet { @@ -71,6 +76,7 @@ open class ImageCard: Card { } } + /// Reloads the view. open override func reload() { var h: CGFloat = 0 @@ -94,6 +100,6 @@ open class ImageCard: Card { } container.height = h - height = h + bounds.size.height = h } } diff --git a/Example/Pods/Material/Sources/iOS/InterimSpace.swift b/Example/Pods/Material/Sources/iOS/InterimSpace.swift index 32154ec..f17d7b7 100644 --- a/Example/Pods/Material/Sources/iOS/InterimSpace.swift +++ b/Example/Pods/Material/Sources/iOS/InterimSpace.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/Example/Pods/Material/Sources/iOS/Layer.swift b/Example/Pods/Material/Sources/iOS/Layer.swift index 6a657f5..a060a80 100644 --- a/Example/Pods/Material/Sources/iOS/Layer.swift +++ b/Example/Pods/Material/Sources/iOS/Layer.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/Example/Pods/Material/Sources/iOS/Layout.swift b/Example/Pods/Material/Sources/iOS/Layout.swift index e9e8633..8a9e1c5 100644 --- a/Example/Pods/Material/Sources/iOS/Layout.swift +++ b/Example/Pods/Material/Sources/iOS/Layout.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -639,6 +639,7 @@ extension Layout { public class func width(parent: UIView, child: UIView, width: CGFloat = 0) { prepareForConstraint(parent, child: child) parent.addConstraint(NSLayoutConstraint(item: child, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .width, multiplier: 1, constant: width)) + child.updateConstraints() child.setNeedsLayout() child.layoutIfNeeded() } @@ -652,6 +653,7 @@ extension Layout { public class func height(parent: UIView, child: UIView, height: CGFloat = 0) { prepareForConstraint(parent, child: child) parent.addConstraint(NSLayoutConstraint(item: child, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 1, constant: height)) + child.updateConstraints() child.setNeedsLayout() child.layoutIfNeeded() } @@ -687,6 +689,7 @@ extension Layout { parent.addConstraint(NSLayoutConstraint(item: children[children.count - 1], attribute: .right, relatedBy: .equal, toItem: parent, attribute: .right, multiplier: 1, constant: -right)) } for child in children { + child.updateConstraints() child.setNeedsLayout() child.layoutIfNeeded() } @@ -703,6 +706,7 @@ extension Layout { */ public class func vertically(parent: UIView, children: [UIView], top: CGFloat = 0, bottom: CGFloat = 0, interimSpace: InterimSpace = 0) { prepareForConstraint(parent, children: children) + if 0 < children.count { parent.addConstraint(NSLayoutConstraint(item: children[0], attribute: .top, relatedBy: .equal, toItem: parent, attribute: .top, multiplier: 1, constant: top)) for i in 1... + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -44,7 +44,7 @@ extension Array where Element: Equatable { } guard -1 < start else { - fatalError("Range out of bounds for \(start) - \(end), should be 0 - \(count).") + fatalError("Range out of bounds for \(start) - \(end ?? 0), should be 0 - \(count).") } var diff = abs(e - start) diff --git a/Example/Pods/Material/Sources/iOS/Material+CALayer.swift b/Example/Pods/Material/Sources/iOS/Material+CALayer.swift index 4db8a79..30c6f8b 100644 --- a/Example/Pods/Material/Sources/iOS/Material+CALayer.swift +++ b/Example/Pods/Material/Sources/iOS/Material+CALayer.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,7 +30,7 @@ import UIKit -fileprivate struct MaterialLayer { +fileprivate class MaterialLayer { /// A reference to the CALayer. fileprivate weak var layer: CALayer? @@ -51,12 +51,16 @@ fileprivate struct MaterialLayer { /// A preset property to set the borderWidth. fileprivate var borderWidthPreset = BorderWidthPreset.none { didSet { - layer?.borderWidth = BorderWidthPresetToValue(preset: borderWidthPreset) + layer?.borderWidth = borderWidthPreset.cgFloatValue } } /// A preset property to set the shape. - fileprivate var shapePreset = ShapePreset.none + fileprivate var shapePreset = ShapePreset.none { + didSet { + layer?.layoutShape() + } + } /// A preset value for Depth. fileprivate var depthPreset: DepthPreset { @@ -94,20 +98,18 @@ fileprivate struct MaterialLayer { } } -/// A memory reference to the MaterialLayer instance for CALayer extensions. fileprivate var MaterialLayerKey: UInt8 = 0 -/// Grid extension for UIView. extension CALayer { /// MaterialLayer Reference. fileprivate var materialLayer: MaterialLayer { get { - return AssociatedObject(base: self, key: &MaterialLayerKey) { + return AssociatedObject.get(base: self, key: &MaterialLayerKey) { return MaterialLayer(layer: self) } } set(value) { - AssociateObject(base: self, key: &MaterialLayerKey, value: value) + AssociatedObject.set(base: self, key: &MaterialLayerKey, value: value) } } @@ -247,62 +249,9 @@ extension CALayer { materialLayer.borderWidthPreset = value } } - - /** - A method that accepts CAAnimation objects and executes them on the - view's backing layer. - - Parameter animation: A CAAnimation instance. - */ - open func animate(animation: CAAnimation) { - animation.delegate = self - - if let a = animation as? CABasicAnimation { - a.fromValue = (presentation() ?? self).value(forKeyPath: a.keyPath!) - } - - if let a = animation as? CAPropertyAnimation { - add(a, forKey: a.keyPath!) - } else if let a = animation as? CAAnimationGroup { - add(a, forKey: nil) - } else if let a = animation as? CATransition { - add(a, forKey: kCATransition) - } - } - - /** - A delegation method that is executed when the backing layer stops - running an animation. - - Parameter animation: The CAAnimation instance that stopped running. - - Parameter flag: A boolean that indicates if the animation stopped - because it was completed or interrupted. True if completed, false - if interrupted. - */ - open func animationDidStop(_ animation: CAAnimation, finished flag: Bool) { - guard let a = animation as? CAPropertyAnimation else { - if let a = (animation as? CAAnimationGroup)?.animations { - for x in a { - animationDidStop(x, finished: true) - } - } - return - } - - guard let b = a as? CABasicAnimation else { - return - } - - guard let v = b.toValue else { - return - } - - guard let k = b.keyPath else { - return - } - - setValue(v, forKeyPath: k) - removeAnimation(forKey: k) - } - +} + +extension CALayer { /// Manages the layout for the shape of the view instance. open func layoutShape() { guard .none != shapePreset else { @@ -312,12 +261,13 @@ extension CALayer { if 0 == frame.width { frame.size.width = frame.height } - + if 0 == frame.height { frame.size.height = frame.width } guard .circle == shapePreset else { + cornerRadius = 0 return } @@ -329,18 +279,13 @@ extension CALayer { guard isShadowPathAutoSizing else { return } - + if .none == depthPreset { shadowPath = nil } else if nil == shadowPath { shadowPath = UIBezierPath(roundedRect: bounds, cornerRadius: cornerRadius).cgPath } else { - let a = Motion.shadowPath(to: UIBezierPath(roundedRect: bounds, cornerRadius: cornerRadius).cgPath) - a.fromValue = shadowPath - animate(animation: a) + animate(.shadow(path: UIBezierPath(roundedRect: bounds, cornerRadius: cornerRadius).cgPath)) } } } - -@available(iOS 10, *) -extension CALayer: CAAnimationDelegate {} diff --git a/Example/Pods/Material/Sources/iOS/Material+Obj-C.swift b/Example/Pods/Material/Sources/iOS/Material+MotionAnimation.swift similarity index 59% rename from Example/Pods/Material/Sources/iOS/Material+Obj-C.swift rename to Example/Pods/Material/Sources/iOS/Material+MotionAnimation.swift index 336e635..1f789d3 100644 --- a/Example/Pods/Material/Sources/iOS/Material+Obj-C.swift +++ b/Example/Pods/Material/Sources/iOS/Material+MotionAnimation.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,30 +28,31 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/** - Gets the Obj-C reference for the instance object within the UIView extension. - - Parameter base: Base object. - - Parameter key: Memory key pointer. - - Parameter initializer: Object initializer. - - Returns: The associated reference for the initializer object. - */ -internal func AssociatedObject(base: Any, key: UnsafePointer, initializer: () -> T) -> T { - if let v = objc_getAssociatedObject(base, key) as? T { - return v +import UIKit + +public extension MotionAnimation { + /** + Animates the view's current shadow offset to the given one. + - Parameter offset: A CGSize. + - Returns: A MotionAnimation. + */ + static func shadow(offset: Offset) -> MotionAnimation { + return .shadow(offset: offset.asSize) } - let v = initializer() - objc_setAssociatedObject(base, key, v, .OBJC_ASSOCIATION_RETAIN) - return v -} - -/** - Sets the Obj-C reference for the instance object within the UIView extension. - - Parameter base: Base object. - - Parameter key: Memory key pointer. - - Parameter value: The object instance to set for the associated object. - - Returns: The associated reference for the initializer object. - */ -internal func AssociateObject(base: Any, key: UnsafePointer, value: T) { - objc_setAssociatedObject(base, key, value, .OBJC_ASSOCIATION_RETAIN) + /** + Animates the views shadow offset, opacity, and radius using a DepthPreset. + - Parameter _ preset: A DepthPreset. + */ + static func depth(_ preset: DepthPreset) -> MotionAnimation { + return .depth(DepthPresetToValue(preset: preset).rawValue) + } + + /** + Animates the views shadow offset, opacity, and radius using a given Depth. + - Parameter _ preset: A Depth. + */ + static func depth(_ depth: Depth) -> MotionAnimation { + return .depth(depth.rawValue) + } } diff --git a/Example/Pods/Material/Sources/iOS/Material+String.swift b/Example/Pods/Material/Sources/iOS/Material+String.swift index 1e4b145..5989da6 100644 --- a/Example/Pods/Material/Sources/iOS/Material+String.swift +++ b/Example/Pods/Material/Sources/iOS/Material+String.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/Example/Pods/Material/Sources/iOS/Material+UIFont.swift b/Example/Pods/Material/Sources/iOS/Material+UIFont.swift index a674a93..bb9d420 100644 --- a/Example/Pods/Material/Sources/iOS/Material+UIFont.swift +++ b/Example/Pods/Material/Sources/iOS/Material+UIFont.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -32,10 +32,14 @@ import UIKit extension UIFont { /** - :name: stringSize - */ - open func stringSize(string: String, constrainedToWidth width: Double) -> CGSize { - return string.boundingRect(with: CGSize(width: width, height: DBL_MAX), + Calculates a CGSize value based on a width and length of a string with a + given UIFont. + - Parameter string: A String. + - Parameter constrainedTo width: A CGFloat. + - Returns a CGSize. + */ + open func stringSize(string: String, constrainedTo width: CGFloat) -> CGSize { + return string.boundingRect(with: CGSize(width: width, height: CGFloat(Double.greatestFiniteMagnitude)), options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes: [NSFontAttributeName: self], context: nil).size diff --git a/Example/Pods/Material/Sources/iOS/Material+UIImage.swift b/Example/Pods/Material/Sources/iOS/Material+UIImage.swift index d168445..24b5ac8 100644 --- a/Example/Pods/Material/Sources/iOS/Material+UIImage.swift +++ b/Example/Pods/Material/Sources/iOS/Material+UIImage.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -131,10 +131,20 @@ extension UIImage { - Returns: A UIImage that is the color passed in. */ open class func image(with color: UIColor, size: CGSize) -> UIImage? { + UIGraphicsBeginImageContextWithOptions(size, false, Screen.scale) + guard let context = UIGraphicsGetCurrentContext() else { + return nil + } + + context.scaleBy(x: 1.0, y: -1.0) + context.translateBy(x: 0.0, y: -size.height) + + context.setBlendMode(.multiply) + let rect = CGRect(x: 0, y: 0, width: size.width, height: size.height) - UIGraphicsBeginImageContextWithOptions(size, false, 0) color.setFill() - UIRectFill(rect) + context.fill(rect) + let image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return image?.withRenderingMode(.alwaysOriginal) @@ -168,7 +178,7 @@ extension UIImage { extension UIImage { /** - Creates an clear image. + Creates a clear image. - Returns: A UIImage that is clear. */ open class func clear(size: CGSize = CGSize(width: 16, height: 16)) -> UIImage? { @@ -217,13 +227,13 @@ extension UIImage { switch imageOrientation { case .down, .downMirrored: transform = transform.translatedBy(x: size.width, y: size.height) - transform = transform.rotated(by: CGFloat(M_PI)) + transform = transform.rotated(by: CGFloat(Double.pi)) case .left, .leftMirrored: transform = transform.translatedBy(x: size.width, y: 0) - transform = transform.rotated(by: CGFloat(M_PI_2)) + transform = transform.rotated(by: CGFloat(Double.pi / 2)) case .right, .rightMirrored: transform = transform.translatedBy(x: 0, y: size.height) - transform = transform.rotated(by: -CGFloat(M_PI_2)) + transform = transform.rotated(by: -CGFloat(Double.pi / 2)) default:break } @@ -286,8 +296,8 @@ extension UIImage { let screenScale = Screen.scale let imageRect = CGRect(origin: .zero, size: size) - let hasBlur = radius > CGFloat(FLT_EPSILON) - let hasSaturationChange = fabs(saturationDeltaFactor - 1.0) > CGFloat(FLT_EPSILON) + let hasBlur = radius > CGFloat(Float.ulpOfOne) + let hasSaturationChange = fabs(saturationDeltaFactor - 1.0) > CGFloat(Float.ulpOfOne) if hasBlur || hasSaturationChange { UIGraphicsBeginImageContextWithOptions(size, false, screenScale) @@ -305,7 +315,7 @@ extension UIImage { var outBuffer = createEffectBuffer(context: outContext) if hasBlur { - let a = sqrt(2 * M_PI) + let a = sqrt(2 * .pi) let b = CGFloat(a) / 4 let c = radius * screenScale let d = c * 3.0 * b diff --git a/Example/Pods/Material/Sources/iOS/Material+UIView.swift b/Example/Pods/Material/Sources/iOS/Material+UIView.swift index 2df9d2d..a81754f 100644 --- a/Example/Pods/Material/Sources/iOS/Material+UIView.swift +++ b/Example/Pods/Material/Sources/iOS/Material+UIView.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,8 +30,40 @@ import UIKit -/// Grid extension for UIView. extension UIView { + /// A property that accesses the backing layer's masksToBounds. + @IBInspectable + open var masksToBounds: Bool { + get { + return layer.masksToBounds + } + set(value) { + layer.masksToBounds = value + } + } + + /// A property that accesses the backing layer's opacity. + @IBInspectable + open var opacity: Float { + get { + return layer.opacity + } + set(value) { + layer.opacity = value + } + } + + /// A property that accesses the backing layer's anchorPoint. + @IBInspectable + open var anchorPoint: CGPoint { + get { + return layer.anchorPoint + } + set(value) { + layer.anchorPoint = value + } + } + /// A property that accesses the frame.origin.x property. @IBInspectable open var x: CGFloat { @@ -268,15 +300,6 @@ extension UIView { } } - /** - A method that accepts CAAnimation objects and executes them on the - view's backing layer. - - Parameter animation: A CAAnimation instance. - */ - open func animate(animation: CAAnimation) { - layer.animate(animation: animation) - } - /// Manages the layout for the shape of the view instance. open func layoutShape() { layer.layoutShape() diff --git a/Example/Pods/Material/Sources/iOS/MotionKeyframe.swift b/Example/Pods/Material/Sources/iOS/Material+UIViewController.swift similarity index 55% rename from Example/Pods/Material/Sources/iOS/MotionKeyframe.swift rename to Example/Pods/Material/Sources/iOS/Material+UIViewController.swift index 57188f3..dabc435 100644 --- a/Example/Pods/Material/Sources/iOS/MotionKeyframe.swift +++ b/Example/Pods/Material/Sources/iOS/Material+UIViewController.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,45 +30,35 @@ import UIKit -@objc(AnimationRotationMode) -public enum AnimationRotationMode: Int { - case `default` - case auto - case autoReverse -} - -/** - Converts an AnimationRotationMode to a corresponding CAAnimationRotate key. - - Parameter mode: An AnimationRotationMode. - - Returns: An optional CAAnimationRotate key String. - */ -public func AnimationRotationModeToValue(mode: AnimationRotationMode) -> String? { - switch mode { - case .default: - return nil - case .auto: - return kCAAnimationRotateAuto - case .autoReverse: - return kCAAnimationRotateAutoReverse - } -} - -extension Motion { - /** - Creates a CAKeyframeAnimation. - - Parameter bezierPath: A UIBezierPath. - - Parameter mode: An AnimationRotationMode. - - Parameter duration: An animation duration time. - - Returns: A CAKeyframeAnimation. +internal extension UIViewController { + /** + Finds a view controller with a given type based on + the view controller subclass. + - Returns: An optional of type T. */ - public static func path(bezierPath: UIBezierPath, mode: AnimationRotationMode = .auto, duration: CFTimeInterval? = nil) -> CAKeyframeAnimation { - let animation = CAKeyframeAnimation() - animation.keyPath = AnimationKeyPath.position.rawValue - animation.path = bezierPath.cgPath - animation.rotationMode = AnimationRotationModeToValue(mode: mode) - if let v = duration { - animation.duration = v - } - return animation - } + func traverseViewControllerHierarchyForClassType() -> T? { + var v: UIViewController? = self + while nil != v { + if v is T { + return v as? T + } + v = v?.parent as? TransitionController + } + + return Application.rootViewController?.traverseTransitionViewControllerHierarchyForClassType() + } + + /** + Traverses the child view controllers to find the correct view controller type T. + - Returns: An optional of type T. + */ + func traverseTransitionViewControllerHierarchyForClassType() -> T? { + if let v = self as? T { + return v + } else if let v = self as? TransitionController { + return v.rootViewController.traverseTransitionViewControllerHierarchyForClassType() + } + + return nil + } } diff --git a/Example/Pods/Material/Sources/iOS/Material+UIWindow.swift b/Example/Pods/Material/Sources/iOS/Material+UIWindow.swift index 0907ff2..6d231e7 100644 --- a/Example/Pods/Material/Sources/iOS/Material+UIWindow.swift +++ b/Example/Pods/Material/Sources/iOS/Material+UIWindow.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/Example/Pods/Material/Sources/iOS/Menu.swift b/Example/Pods/Material/Sources/iOS/Menu.swift deleted file mode 100644 index 31e514e..0000000 --- a/Example/Pods/Material/Sources/iOS/Menu.swift +++ /dev/null @@ -1,613 +0,0 @@ -/* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, 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 of CosmicMind 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. - */ - -import UIKit - -@objc(MenuDirection) -public enum MenuDirection: Int { - case up - case down - case left - case right -} - -@objc(MenuDelegate) -public protocol MenuDelegate { - /** - Gets called when the user taps while the menu is opened. - - Parameter menu: A Menu. - - Parameter tappedAt point: A CGPoint. - - Parameter isOutside: A boolean indicating whether the tap - was outside the menu button area. - */ - @objc - optional func menu(menu: Menu, tappedAt point: CGPoint, isOutside: Bool) -} - -open class Menu: View { - /// A Boolean that indicates if the menu is open or not. - open internal(set) var isOpened = false - - /// Enables the animations for the Menu. - open internal(set) var isEnabled = true - - /// A preset wrapper around interimSpace. - open var interimSpacePreset = InterimSpacePreset.none { - didSet { - interimSpace = InterimSpacePresetToValue(preset: interimSpacePreset) - } - } - - /// The space between views. - open var interimSpace: InterimSpace = 0 { - didSet { - layoutSubviews() - } - } - - /// The direction in which the animation opens the menu. - open var direction = MenuDirection.up { - didSet { - layoutSubviews() - } - } - - /// A delegation reference. - open weak var delegate: MenuDelegate? - - /// An Array of UIViews. - open var views = [UIView]() { - didSet { - for v in oldValue { - v.removeFromSuperview() - } - - for v in views { - addSubview(v) - } - - layoutSubviews() - } - } - - /// An Optional base view size. - open var baseSize = CGSize(width: 48, height: 48) - - /// Size of views, not including the first view. - open var itemSize = CGSize(width: 48, height: 48) - - open override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { - guard isOpened, isEnabled else { - return super.hitTest(point, with: event) - } - - for v in subviews { - let p = v.convert(point, from: self) - if v.bounds.contains(p) { - delegate?.menu?(menu: self, tappedAt: point, isOutside: false) - return v.hitTest(p, with: event) - } - } - - delegate?.menu?(menu: self, tappedAt: point, isOutside: true) - - return self.hitTest(point, with: event) - } - - /** - Prepares the view instance when intialized. When subclassing, - it is recommended to override the prepare method - to initialize property values and other setup operations. - The super.prepare method should always be called immediately - when subclassing. - */ - open override func prepare() { - super.prepare() - backgroundColor = nil - interimSpacePreset = .interimSpace6 - } - - open override func layoutSubviews() { - super.layoutSubviews() - reload() - } - - /// Reload the view layout. - open func reload() { - isOpened = false - guard let base = views.first else { - return - } - - base.frame.size = baseSize - base.zPosition = 10000 - - for i in 1.. Void)? = nil, completion: ((UIView) -> Void)? = nil) { - if isEnabled { - disable() - switch direction { - case .up: - openUpAnimation(duration: duration, delay: delay, usingSpringWithDamping: usingSpringWithDamping, initialSpringVelocity: initialSpringVelocity, options: options, animations: animations, completion: completion) - case .down: - openDownAnimation(duration: duration, delay: delay, usingSpringWithDamping: usingSpringWithDamping, initialSpringVelocity: initialSpringVelocity, options: options, animations: animations, completion: completion) - case .left: - openLeftAnimation(duration: duration, delay: delay, usingSpringWithDamping: usingSpringWithDamping, initialSpringVelocity: initialSpringVelocity, options: options, animations: animations, completion: completion) - case .right: - openRightAnimation(duration: duration, delay: delay, usingSpringWithDamping: usingSpringWithDamping, initialSpringVelocity: initialSpringVelocity, options: options, animations: animations, completion: completion) - } - } - } - - /** - Close the Menu component with animation options. - - Parameter duration: The time for each view's animation. - - Parameter delay: A delay time for each view's animation. - - Parameter usingSpringWithDamping: A damping ratio for the animation. - - Parameter initialSpringVelocity: The initial velocity for the animation. - - Parameter options: Options to pass to the animation. - - Parameter animations: An animation block to execute on each view's animation. - - Parameter completion: A completion block to execute on each view's animation. - */ - open func close(duration: TimeInterval = 0.15, delay: TimeInterval = 0, usingSpringWithDamping: CGFloat = 0.5, initialSpringVelocity: CGFloat = 0, options: UIViewAnimationOptions = [], animations: ((UIView) -> Void)? = nil, completion: ((UIView) -> Void)? = nil) { - if isEnabled { - disable() - switch direction { - case .up: - closeUpAnimation(duration: duration, delay: delay, usingSpringWithDamping: usingSpringWithDamping, initialSpringVelocity: initialSpringVelocity, options: options, animations: animations, completion: completion) - case .down: - closeDownAnimation(duration: duration, delay: delay, usingSpringWithDamping: usingSpringWithDamping, initialSpringVelocity: initialSpringVelocity, options: options, animations: animations, completion: completion) - case .left: - closeLeftAnimation(duration: duration, delay: delay, usingSpringWithDamping: usingSpringWithDamping, initialSpringVelocity: initialSpringVelocity, options: options, animations: animations, completion: completion) - case .right: - closeRightAnimation(duration: duration, delay: delay, usingSpringWithDamping: usingSpringWithDamping, initialSpringVelocity: initialSpringVelocity, options: options, animations: animations, completion: completion) - } - } - } -} - -extension Menu { - /** - Open the Menu component with animation options in the Up direction. - - Parameter duration: The time for each view's animation. - - Parameter delay: A delay time for each view's animation. - - Parameter usingSpringWithDamping: A damping ratio for the animation. - - Parameter initialSpringVelocity: The initial velocity for the animation. - - Parameter options: Options to pass to the animation. - - Parameter animations: An animation block to execute on each view's animation. - - Parameter completion: A completion block to execute on each view's animation. - */ - fileprivate func openUpAnimation(duration: TimeInterval, delay: TimeInterval, usingSpringWithDamping: CGFloat, initialSpringVelocity: CGFloat, options: UIViewAnimationOptions, animations: ((UIView) -> Void)?, completion: ((UIView) -> Void)?) { - guard let base = views.first else { - return - } - - for i in 1.. Void)?, completion: ((UIView) -> Void)?) { - guard let base = views.first else { - return - } - - for i in 1.. Void)?, completion: ((UIView) -> Void)?) { - guard let base = views.first else { - return - } - - let h = baseSize.height - - for i in 1.. Void)?, completion: ((UIView) -> Void)?) { - guard let base = views.first else { - return - } - - let h = baseSize.height - - for i in 1.. Void)?, completion: ((UIView) -> Void)?) { - guard let base = views.first else { - return - } - - for i in 1.. Void)?, completion: ((UIView) -> Void)?) { - guard let base = views.first else { - return - } - - for i in 1.. Void)?, completion: ((UIView) -> Void)?) { - guard let base = views.first else { - return - } - - let h = baseSize.height - - for i in 1.. Void)?, completion: ((UIView) -> Void)?) { - guard let base = views.first else { - return - } - - let w = baseSize.width - - for i in 1... - * 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 of CosmicMind 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. - */ - -import UIKit - -extension UIViewController { - /** - A convenience property that provides access to the MenuController. - This is the recommended method of accessing the MenuController - through child UIViewControllers. - */ - public var menuController: MenuController? { - var viewController: UIViewController? = self - while nil != viewController { - if viewController is MenuController { - return viewController as? MenuController - } - viewController = viewController?.parent - } - return nil - } -} - -open class MenuController: RootController { - /// Reference to the MenuView. - @IBInspectable - open let menu = Menu() - - open override func layoutSubviews() { - super.layoutSubviews() - rootViewController.view.frame = view.bounds - } - - /** - Prepares the view instance when intialized. When subclassing, - it is recommended to override the prepare method - to initialize property values and other setup operations. - The super.prepare method should always be called immediately - when subclassing. - */ - open override func prepare() { - super.prepare() - prepareMenu() - } -} - -extension MenuController { - /// Prepares the Menu. - fileprivate func prepareMenu() { - menu.zPosition = 1000 - view.addSubview(menu) - } -} - -extension MenuController { - /** - Opens the menu with a callback. - - Parameter completion: An Optional callback that is executed when - all menu items have been opened. - */ - open func openMenu(completion: ((UIView) -> Void)? = nil) { - if true == isUserInteractionEnabled { - isUserInteractionEnabled = false - UIView.animate(withDuration: 0.15, animations: { [weak self] in - guard let s = self else { - return - } - s.rootViewController.view.alpha = 0.15 - }) - menu.open { [completion = completion] (view) in - completion?(view) - } - } - } - - /** - Opens the menu with a callback. - - Parameter completion: An Optional callback that is executed when - all menu items have been closed. - */ - open func closeMenu(completion: ((UIView) -> Void)? = nil) { - if false == isUserInteractionEnabled { - UIView.animate(withDuration: 0.15, animations: { [weak self] in - guard let s = self else { - return - } - s.rootViewController.view.alpha = 1 - }) - menu.close { [weak self] (view) in - guard let s = self else { - return - } - - completion?(view) - - if view == s.menu.views.last { - s.isUserInteractionEnabled = true - } - } - } - } -} diff --git a/Example/Pods/Material/Sources/iOS/MenuItem.swift b/Example/Pods/Material/Sources/iOS/MenuItem.swift deleted file mode 100644 index b4c6cb1..0000000 --- a/Example/Pods/Material/Sources/iOS/MenuItem.swift +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, 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 of CosmicMind 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. - */ - -import UIKit - -open class MenuItem: View { - /// A reference to the titleLabel. - open let titleLabel = UILabel() - - /// A reference to the button. - open let button = FabButton() - - /** - Prepares the view instance when intialized. When subclassing, - it is recommended to override the prepare method - to initialize property values and other setup operations. - The super.prepare method should always be called immediately - when subclassing. - */ - open override func prepare() { - super.prepare() - backgroundColor = nil - - prepareButton() - prepareTitleLabel() - } - - /// A reference to the titleLabel text. - open var title: String? { - get { - return titleLabel.text - } - set(value) { - titleLabel.text = value - hideTitleLabel() - } - } - - /// Shows the titleLabel. - open func showTitleLabel() { - let interimSpace = InterimSpacePresetToValue(preset: .interimSpace6) - - titleLabel.sizeToFit() - titleLabel.width += 1.5 * interimSpace - titleLabel.height += interimSpace / 2 - titleLabel.y = (height - titleLabel.height) / 2 - titleLabel.x = -titleLabel.width - interimSpace - titleLabel.alpha = 0 - titleLabel.isHidden = false - - UIView.animate(withDuration: 0.25, animations: { [weak self] in - guard let s = self else { - return - } - - s.titleLabel.alpha = 1 - }) - } - - /// Hides the titleLabel. - open func hideTitleLabel() { - titleLabel.isHidden = true - } - - /// Prepares the button. - private func prepareButton() { - layout(button).edges() - } - - /// Prepares the titleLabel. - private func prepareTitleLabel() { - titleLabel.font = RobotoFont.regular(with: 14) - titleLabel.textAlignment = .center - titleLabel.backgroundColor = .white - titleLabel.depthPreset = button.depthPreset - titleLabel.cornerRadiusPreset = .cornerRadius1 - addSubview(titleLabel) - } -} diff --git a/Example/Pods/Material/Sources/iOS/Motion.swift b/Example/Pods/Material/Sources/iOS/Motion.swift deleted file mode 100644 index 8f3dc5b..0000000 --- a/Example/Pods/Material/Sources/iOS/Motion.swift +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, 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 of CosmicMind 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. - */ - -import UIKit - -@objc(AnimationFillMode) -public enum AnimationFillMode: Int { - case forwards - case backwards - case both - case removed -} - -/** - Converts the AnimationFillMode enum value to a corresponding String. - - Parameter mode: An AnimationFillMode enum value. - */ -public func AnimationFillModeToValue(mode: AnimationFillMode) -> String { - switch mode { - case .forwards: - return kCAFillModeForwards - case .backwards: - return kCAFillModeBackwards - case .both: - return kCAFillModeBoth - case .removed: - return kCAFillModeRemoved - } -} - -@objc(AnimationTimingFunction) -public enum AnimationTimingFunction: Int { - case `default` - case linear - case easeIn - case easeOut - case easeInEaseOut -} - -/** - Converts the AnimationTimingFunction enum value to a corresponding CAMediaTimingFunction. - - Parameter function: An AnimationTimingFunction enum value. - - Returns: A CAMediaTimingFunction. - */ -public func AnimationTimingFunctionToValue(function: AnimationTimingFunction) -> CAMediaTimingFunction { - switch function { - case .default: - return CAMediaTimingFunction(name: kCAMediaTimingFunctionDefault) - case .linear: - return CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear) - case .easeIn: - return CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn) - case .easeOut: - return CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut) - case .easeInEaseOut: - return CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut) - } -} - -public typealias MotionDelayCancelBlock = (Bool) -> Void - -public struct Motion { - /** - Executes a block of code after a time delay. - - Parameter duration: An animation duration time. - - Parameter animations: An animation block. - - Parameter execute block: A completion block that is executed once - the animations have completed. - */ - @discardableResult - public static func delay(time: TimeInterval, execute block: @escaping () -> Void) -> MotionDelayCancelBlock? { - - func asyncAfter(completion: @escaping () -> Void) { - DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + time, execute: completion) - } - - var cancelable: MotionDelayCancelBlock? - - let delayed: MotionDelayCancelBlock = { - if !$0 { - DispatchQueue.main.async(execute: block) - } - - cancelable = nil - } - - cancelable = delayed - - asyncAfter { - cancelable?(false) - } - - return cancelable; - } - - /** - Cancels the delayed MotionDelayCancelBlock. - - Parameter delayed completion: An MotionDelayCancelBlock. - */ - public static func cancel(delayed completion: MotionDelayCancelBlock) { - completion(true) - } - - /** - Disables the default animations set on CALayers. - - Parameter animations: A callback that wraps the animations to disable. - */ - public static func disable(animations: (() -> Void)) { - animate(duration: 0, animations: animations) - } - - /** - Runs an animation with a specified duration. - - Parameter duration: An animation duration time. - - Parameter animations: An animation block. - - Parameter timingFunction: An AnimationTimingFunction value. - - Parameter completion: A completion block that is executed once - the animations have completed. - */ - public static func animate(duration: CFTimeInterval, timingFunction: AnimationTimingFunction = .easeInEaseOut, animations: (() -> Void), completion: (() -> Void)? = nil) { - CATransaction.begin() - CATransaction.setAnimationDuration(duration) - CATransaction.setCompletionBlock(completion) - CATransaction.setAnimationTimingFunction(AnimationTimingFunctionToValue(function: .easeInEaseOut)) - animations() - CATransaction.commit() - } - - /** - Creates a CAAnimationGroup. - - Parameter animations: An Array of CAAnimation objects. - - Parameter timingFunction: An AnimationTimingFunction value. - - Parameter duration: An animation duration time for the group. - - Returns: A CAAnimationGroup. - */ - public static func animate(group animations: [CAAnimation], timingFunction: AnimationTimingFunction = .easeInEaseOut, duration: CFTimeInterval = 0.5) -> CAAnimationGroup { - let group = CAAnimationGroup() - group.fillMode = AnimationFillModeToValue(mode: .forwards) - group.isRemovedOnCompletion = false - group.animations = animations - group.duration = duration - group.timingFunction = AnimationTimingFunctionToValue(function: timingFunction) - return group - } - - /** - Executes an animation block with a given delay and duration. - - Parameter delay time: A CFTimeInterval. - - Parameter duration: An animation duration time. - - Parameter animations: An animation block. - - Parameter completion: A completion block that is executed once - the animations have completed. - */ - public static func animate(delay time: CFTimeInterval, duration: CFTimeInterval, animations: @escaping (() -> Void), completion: (() -> Void)? = nil) { - delay(time: time) { - animate(duration: duration, animations: animations, completion: completion) - } - } -} - diff --git a/Example/Pods/Material/Sources/iOS/MotionBasic.swift b/Example/Pods/Material/Sources/iOS/MotionBasic.swift deleted file mode 100644 index 545b90a..0000000 --- a/Example/Pods/Material/Sources/iOS/MotionBasic.swift +++ /dev/null @@ -1,423 +0,0 @@ -/* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, 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 of CosmicMind 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. - */ - -import UIKit - -public enum AnimationKeyPath: String { - case backgroundColor - case cornerRadius - case transform - case rotation = "transform.rotation" - case rotationX = "transform.rotation.x" - case rotationY = "transform.rotation.y" - case rotationZ = "transform.rotation.z" - case scale = "transform.scale" - case scaleX = "transform.scale.x" - case scaleY = "transform.scale.y" - case scaleZ = "transform.scale.z" - case translation = "transform.translation" - case translationX = "transform.translation.x" - case translationY = "transform.translation.y" - case translationZ = "transform.translation.z" - case position - case shadowPath -} - -extension CABasicAnimation { - /** - A convenience initializer that takes a given AnimationKeyPath. - - Parameter keyPath: An AnimationKeyPath. - */ - public convenience init(keyPath: AnimationKeyPath) { - self.init(keyPath: keyPath.rawValue) - } -} - -extension Motion { - /** - Creates a CABasicAnimation for the backgroundColor key path. - - Parameter color: A UIColor. - - Parameter duration: An animation time duration. - - Returns: A CABasicAnimation. - */ - public static func backgroundColor(color: UIColor, duration: CFTimeInterval? = nil) -> CABasicAnimation { - let animation = CABasicAnimation(keyPath: .backgroundColor) - animation.toValue = color.cgColor - animation.fillMode = AnimationFillModeToValue(mode: .forwards) - animation.isRemovedOnCompletion = false - animation.timingFunction = AnimationTimingFunctionToValue(function: .easeInEaseOut) - - if let v = duration { - animation.duration = v - } - - return animation - } - - /** - Creates a CABasicAnimation for the cornerRadius key path. - - Parameter radius: A CGFloat. - - Parameter duration: An animation time duration. - - Returns: A CABasicAnimation. - */ - public static func cornerRadius(radius: CGFloat, duration: CFTimeInterval? = nil) -> CABasicAnimation { - let animation = CABasicAnimation(keyPath: .cornerRadius) - animation.toValue = radius - animation.fillMode = AnimationFillModeToValue(mode: .forwards) - animation.isRemovedOnCompletion = false - animation.timingFunction = AnimationTimingFunctionToValue(function: .easeInEaseOut) - - if let v = duration { - animation.duration = v - } - - return animation - } - - /** - Creates a CABasicAnimation for the transform key path. - - Parameter transform: A CATransform3D object. - - Parameter duration: An animation time duration. - - Returns: A CABasicAnimation. - */ - public static func transform(transform: CATransform3D, duration: CFTimeInterval? = nil) -> CABasicAnimation { - let animation = CABasicAnimation(keyPath: .transform) - - animation.toValue = NSValue(caTransform3D: transform) - animation.fillMode = AnimationFillModeToValue(mode: .forwards) - animation.isRemovedOnCompletion = false - animation.timingFunction = AnimationTimingFunctionToValue(function: .easeInEaseOut) - - if let v = duration { - animation.duration = v - } - - return animation - } - - /** - Creates a CABasicAnimation for the transform.rotation key path. - - Parameter angle: An optional CGFloat. - - Parameter rotation: An optional CGFloat. - - Parameter duration: An animation time duration. - - Returns: A CABasicAnimation. - */ - public static func rotate(angle: CGFloat? = nil, rotation: CGFloat? = nil, duration: CFTimeInterval? = nil) -> CABasicAnimation { - let animation = CABasicAnimation(keyPath: .rotation) - - if let v = angle { - animation.toValue = (CGFloat(M_PI) * v / 180) as NSNumber - } else if let v = rotation { - animation.toValue = (CGFloat(M_PI * 2) * v) as NSNumber - } - - animation.fillMode = AnimationFillModeToValue(mode: .forwards) - animation.isRemovedOnCompletion = false - animation.timingFunction = AnimationTimingFunctionToValue(function: .easeInEaseOut) - - if let v = duration { - animation.duration = v - } - return animation - } - - /** - Creates a CABasicAnimation for the transform.rotation.x key path. - - Parameter angle: An optional CGFloat. - - Parameter rotation: An optional CGFloat. - - Parameter duration: An animation time duration. - - Returns: A CABasicAnimation. - */ - public static func rotateX(angle: CGFloat? = nil, rotation: CGFloat? = nil, duration: CFTimeInterval? = nil) -> CABasicAnimation { - let animation = CABasicAnimation(keyPath: .rotationX) - - if let v: CGFloat = angle { - animation.toValue = (CGFloat(M_PI) * v / 180) as NSNumber - } else if let v: CGFloat = rotation { - animation.toValue = (CGFloat(M_PI * 2) * v) as NSNumber - } - - animation.fillMode = AnimationFillModeToValue(mode: .forwards) - animation.isRemovedOnCompletion = false - animation.timingFunction = AnimationTimingFunctionToValue(function: .easeInEaseOut) - - if let v = duration { - animation.duration = v - } - - return animation - } - - /** - Creates a CABasicAnimation for the transform.rotation.y key path. - - Parameter angle: An optional CGFloat. - - Parameter rotation: An optional CGFloat. - - Parameter duration: An animation time duration. - - Returns: A CABasicAnimation. - */ - public static func rotateY(angle: CGFloat? = nil, rotation: CGFloat? = nil, duration: CFTimeInterval? = nil) -> CABasicAnimation { - let animation = CABasicAnimation(keyPath: .rotationY) - - if let v = angle { - animation.toValue = (CGFloat(M_PI) * v / 180) as NSNumber - } else if let v = rotation { - animation.toValue = (CGFloat(M_PI * 2) * v) as NSNumber - } - - animation.fillMode = AnimationFillModeToValue(mode: .forwards) - animation.isRemovedOnCompletion = false - animation.timingFunction = AnimationTimingFunctionToValue(function: .easeInEaseOut) - - if let v = duration { - animation.duration = v - } - - return animation - } - - /** - Creates a CABasicAnimation for the transform.rotation.z key path. - - Parameter angle: An optional CGFloat. - - Parameter rotation: An optional CGFloat. - - Parameter duration: An animation time duration. - - Returns: A CABasicAnimation. - */ - public static func rotateZ(angle: CGFloat? = nil, rotation: CGFloat? = nil, duration: CFTimeInterval? = nil) -> CABasicAnimation { - let animation = CABasicAnimation(keyPath: .rotationZ) - - if let v = angle { - animation.toValue = (CGFloat(M_PI) * v / 180) as NSNumber - } else if let v = rotation { - animation.toValue = (CGFloat(M_PI * 2) * v) as NSNumber - } - - animation.fillMode = AnimationFillModeToValue(mode: .forwards) - animation.isRemovedOnCompletion = false - animation.timingFunction = AnimationTimingFunctionToValue(function: .easeInEaseOut) - - if let v = duration { - animation.duration = v - } - - return animation - } - - /** - Creates a CABasicAnimation for the transform.scale key path. - - Parameter by scale: A CGFloat. - - Parameter duration: An animation time duration. - - Returns: A CABasicAnimation. - */ - public static func scale(by scale: CGFloat, duration: CFTimeInterval? = nil) -> CABasicAnimation { - let animation = CABasicAnimation(keyPath: .scale) - animation.toValue = scale as NSNumber - animation.fillMode = AnimationFillModeToValue(mode: .forwards) - animation.isRemovedOnCompletion = false - animation.timingFunction = AnimationTimingFunctionToValue(function: .easeInEaseOut) - if let v = duration { - animation.duration = v - } - return animation - } - - /** - Creates a CABasicAnimation for the transform.scale.x key path. - - Parameter by scale: A CGFloat. - - Parameter duration: An animation time duration. - - Returns: A CABasicAnimation. - */ - public static func scaleX(by scale: CGFloat, duration: CFTimeInterval? = nil) -> CABasicAnimation { - let animation = CABasicAnimation(keyPath: .scaleX) - animation.toValue = scale as NSNumber - animation.fillMode = AnimationFillModeToValue(mode: .forwards) - animation.isRemovedOnCompletion = false - animation.timingFunction = AnimationTimingFunctionToValue(function: .easeInEaseOut) - if let v = duration { - animation.duration = v - } - return animation - } - - /** - Creates a CABasicAnimation for the transform.scale.y key path. - - Parameter by scale: A CGFloat. - - Parameter duration: An animation time duration. - - Returns: A CABasicAnimation. - */ - public static func scaleY(by scale: CGFloat, duration: CFTimeInterval? = nil) -> CABasicAnimation { - let animation = CABasicAnimation(keyPath: .scaleY) - animation.toValue = scale as NSNumber - animation.fillMode = AnimationFillModeToValue(mode: .forwards) - animation.isRemovedOnCompletion = false - animation.timingFunction = AnimationTimingFunctionToValue(function: .easeInEaseOut) - if let v = duration { - animation.duration = v - } - return animation - } - - /** - Creates a CABasicAnimation for the transform.scale.z key path. - - Parameter by scale: A CGFloat. - - Parameter duration: An animation time duration. - - Returns: A CABasicAnimation. - */ - public static func scaleZ(by scale: CGFloat, duration: CFTimeInterval? = nil) -> CABasicAnimation { - let animation = CABasicAnimation(keyPath: .scaleZ) - animation.toValue = scale as NSNumber - animation.fillMode = AnimationFillModeToValue(mode: .forwards) - animation.isRemovedOnCompletion = false - animation.timingFunction = AnimationTimingFunctionToValue(function: .easeInEaseOut) - if let v = duration { - animation.duration = v - } - return animation - } - - /** - Creates a CABasicAnimation for the transform.translation key path. - - Parameter size: A CGSize. - - Parameter duration: An animation time duration. - - Returns: A CABasicAnimation. - */ - public static func translate(size: CGSize, duration: CFTimeInterval? = nil) -> CABasicAnimation { - let animation = CABasicAnimation(keyPath: .translation) - animation.toValue = NSValue(cgSize: size) - animation.fillMode = AnimationFillModeToValue(mode: .forwards) - animation.isRemovedOnCompletion = false - animation.timingFunction = AnimationTimingFunctionToValue(function: .easeInEaseOut) - - if let v = duration { - animation.duration = v - } - - return animation - } - - /** - Creates a CABasicAnimation for the transform.translation.x key path. - - Parameter by translation: A CGFloat. - - Parameter duration: An animation time duration. - - Returns: A CABasicAnimation. - */ - public static func translateX(by translation: CGFloat, duration: CFTimeInterval? = nil) -> CABasicAnimation { - let animation = CABasicAnimation(keyPath: .translationX) - animation.toValue = translation as NSNumber - animation.fillMode = AnimationFillModeToValue(mode: .forwards) - animation.isRemovedOnCompletion = false - animation.timingFunction = AnimationTimingFunctionToValue(function: .easeInEaseOut) - - if let v = duration { - animation.duration = v - } - - return animation - } - - /** - Creates a CABasicAnimation for the transform.translation.y key path. - - Parameter by translation: A CGFloat. - - Parameter duration: An animation time duration. - - Returns: A CABasicAnimation. - */ - public static func translateY(by translation: CGFloat, duration: CFTimeInterval? = nil) -> CABasicAnimation { - let animation = CABasicAnimation(keyPath: .translationY) - animation.toValue = translation as NSNumber - animation.fillMode = AnimationFillModeToValue(mode: .forwards) - animation.isRemovedOnCompletion = false - animation.timingFunction = AnimationTimingFunctionToValue(function: .easeInEaseOut) - - if let v = duration { - animation.duration = v - } - - return animation - } - - /** - Creates a CABasicAnimation for the transform.translation.z key path. - - Parameter by translation: A CGFloat. - - Parameter duration: An animation time duration. - - Returns: A CABasicAnimation. - */ - public static func translateZ(by translation: CGFloat, duration: CFTimeInterval? = nil) -> CABasicAnimation { - let animation = CABasicAnimation(keyPath: .translationZ) - animation.toValue = translation as NSNumber - animation.fillMode = AnimationFillModeToValue(mode: .forwards) - animation.isRemovedOnCompletion = false - animation.timingFunction = AnimationTimingFunctionToValue(function: .easeInEaseOut) - - if let v = duration { - animation.duration = v - } - - return animation - } - - /** - Creates a CABasicAnimation for the position key path. - - Parameter to point: A CGPoint. - - Parameter duration: An animation time duration. - - Returns: A CABasicAnimation. - */ - public static func position(to point: CGPoint, duration: CFTimeInterval? = nil) -> CABasicAnimation { - let animation = CABasicAnimation(keyPath: .position) - animation.toValue = NSValue(cgPoint: point) - animation.fillMode = AnimationFillModeToValue(mode: .forwards) - animation.isRemovedOnCompletion = false - animation.timingFunction = AnimationTimingFunctionToValue(function: .easeInEaseOut) - - if let v = duration { - animation.duration = v - } - - return animation - } - - /** - Creates a CABasicAnimation for the shadowPath key path. - - Parameter to path: A CGPath. - - Parameter duration: An animation time duration. - - Returns: A CABasicAnimation. - */ - public static func shadowPath(to path: CGPath, duration: CFTimeInterval? = nil) -> CABasicAnimation { - let animation = CABasicAnimation(keyPath: .shadowPath) - animation.toValue = path - animation.fillMode = AnimationFillModeToValue(mode: .forwards) - animation.isRemovedOnCompletion = false - animation.timingFunction = AnimationTimingFunctionToValue(function: .linear) - - if let v = duration { - animation.duration = v - } - - return animation - } -} diff --git a/Example/Pods/Material/Sources/iOS/MotionTransition.swift b/Example/Pods/Material/Sources/iOS/MotionTransition.swift deleted file mode 100644 index c3baa67..0000000 --- a/Example/Pods/Material/Sources/iOS/MotionTransition.swift +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, 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 of CosmicMind 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. - */ - -import UIKit - -@objc(AnimationTransition) -public enum AnimationTransition: Int { - case fade - case moveIn - case push - case reveal -} - -@objc(AnimationTransitionDirection) -public enum AnimationTransitionDirection: Int { - case `default` - case right - case left - case top - case bottom -} - -/** - Converts an AnimationTransition to a corresponding CATransition key. - - Parameter transition: An AnimationTransition. - - Returns: A CATransition key String. - */ -public func AnimationTransitionToValue(transition type: AnimationTransition) -> String { - switch type { - case .fade: - return kCATransitionFade - case .moveIn: - return kCATransitionMoveIn - case .push: - return kCATransitionPush - case .reveal: - return kCATransitionReveal - } -} - -/** - Converts an AnimationTransitionDirection to a corresponding CATransition direction key. - - Parameter direction: An AnimationTransitionDirection. - - Returns: An optional CATransition direction key String. - */ -public func AnimationTransitionDirectionToValue(direction: AnimationTransitionDirection) -> String? { - switch direction { - case .default: - return nil - case .right: - return kCATransitionFromRight - case .left: - return kCATransitionFromLeft - case .top: - return kCATransitionFromBottom - case .bottom: - return kCATransitionFromTop - } -} - -extension Motion { - /** - Creates a CATransition animation. - - Parameter type: An AnimationTransition. - - Parameter direction: An optional AnimationTransitionDirection. - - Parameter duration: An optional duration time. - - Returns: A CATransition. - */ - public static func transition(type: AnimationTransition, direction: AnimationTransitionDirection = .default, duration: CFTimeInterval? = nil) -> CATransition { - let animation = CATransition() - animation.type = AnimationTransitionToValue(transition: type) - animation.subtype = AnimationTransitionDirectionToValue(direction: direction) - - if let v = duration { - animation.duration = v - } - - return animation - } -} diff --git a/Example/Pods/Material/Sources/iOS/NavigationBar.swift b/Example/Pods/Material/Sources/iOS/NavigationBar.swift index de522b9..39a107a 100644 --- a/Example/Pods/Material/Sources/iOS/NavigationBar.swift +++ b/Example/Pods/Material/Sources/iOS/NavigationBar.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -98,9 +98,12 @@ open class NavigationBar: UINavigationBar { /// A property that accesses the backing layer's background @IBInspectable open override var backgroundColor: UIColor? { - didSet { - barTintColor = backgroundColor - } + get { + return barTintColor + } + set(value) { + barTintColor = value + } } /** @@ -145,7 +148,7 @@ open class NavigationBar: UINavigationBar { layoutNavigationItem(item: v) } - divider.reload() + layoutDivider() } open override func pushItem(_ item: UINavigationItem, animated: Bool) { @@ -293,8 +296,9 @@ open class NavigationBar: UINavigationBar { contentEdgeInsetsPreset = .square1 contentScaleFactor = Screen.scale backButtonImage = Icon.cm.arrowBack - let image = UIImage.image(with: .clear, size: CGSize(width: 1, height: 1)) - shadowImage = image + + let image = UIImage() + shadowImage = image setBackgroundImage(image, for: .default) backgroundColor = .white } diff --git a/Example/Pods/Material/Sources/iOS/NavigationController.swift b/Example/Pods/Material/Sources/iOS/NavigationController.swift index 60de9aa..4ab434c 100644 --- a/Example/Pods/Material/Sources/iOS/NavigationController.swift +++ b/Example/Pods/Material/Sources/iOS/NavigationController.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,7 +30,7 @@ import UIKit -extension UINavigationController { +extension NavigationController { /// Device status bar style. open var statusBarStyle: UIStatusBarStyle { get { @@ -108,7 +108,7 @@ open class NavigationController: UINavigationController { open override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() - navigationBar.width = view.width + layoutSubviews() } /** @@ -132,6 +132,13 @@ open class NavigationController: UINavigationController { v.delegate = self } } + + /// Calls the layout functions for the view heirarchy. + open func layoutSubviews() { + navigationBar.updateConstraints() + navigationBar.setNeedsLayout() + navigationBar.layoutIfNeeded() + } } extension NavigationController: UINavigationBarDelegate { @@ -145,9 +152,16 @@ extension NavigationController: UINavigationBarDelegate { */ public func navigationBar(_ navigationBar: UINavigationBar, shouldPush item: UINavigationItem) -> Bool { if let v = navigationBar as? NavigationBar { + if nil == item.backButton.image && nil == item.backButton.title { + item.backButton.image = v.backButtonImage + } + item.backButton.addTarget(self, action: #selector(handleBackButton), for: .touchUpInside) - item.backButton.image = v.backButtonImage - item.leftViews.insert(item.backButton, at: 0) + + if !item.backButton.isHidden { + item.leftViews.insert(item.backButton, at: 0) + } + v.layoutNavigationItem(item: item) } return true diff --git a/Example/Pods/Material/Sources/iOS/NavigationDrawerController.swift b/Example/Pods/Material/Sources/iOS/NavigationDrawerController.swift index 6b829da..b5c7ae7 100644 --- a/Example/Pods/Material/Sources/iOS/NavigationDrawerController.swift +++ b/Example/Pods/Material/Sources/iOS/NavigationDrawerController.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -38,19 +38,12 @@ public enum NavigationDrawerPosition: Int { extension UIViewController { /** - A convenience property that provides access to the NavigationDrawerController. - This is the recommended method of accessing the NavigationDrawerController - through child UIViewControllers. - */ + A convenience property that provides access to the NavigationDrawerController. + This is the recommended method of accessing the NavigationDrawerController + through child UIViewControllers. + */ public var navigationDrawerController: NavigationDrawerController? { - var viewController: UIViewController? = self - while nil != viewController { - if viewController is NavigationDrawerController { - return viewController as? NavigationDrawerController - } - viewController = viewController?.parent - } - return nil + return traverseViewControllerHierarchyForClassType() } } @@ -143,7 +136,7 @@ public protocol NavigationDrawerControllerDelegate { } @objc(NavigationDrawerController) -open class NavigationDrawerController: RootController { +open class NavigationDrawerController: TransitionController { /** A CGFloat property that is used internally to track the original (x) position of the container view when panning. @@ -181,7 +174,8 @@ open class NavigationDrawerController: RootController { the leftView is opened, if it is below the threshold, the leftView is closed. */ - @IBInspectable public var leftThreshold: CGFloat = 64 + @IBInspectable + open var leftThreshold: CGFloat = 64 fileprivate var leftViewThreshold: CGFloat = 0 /** @@ -191,7 +185,8 @@ open class NavigationDrawerController: RootController { the rightView is closed, if it is below the threshold, the rightView is opened. */ - @IBInspectable public var rightThreshold: CGFloat = 64 + @IBInspectable + open var rightThreshold: CGFloat = 64 fileprivate var rightViewThreshold: CGFloat = 0 /** @@ -332,18 +327,18 @@ open class NavigationDrawerController: RootController { /// indicates if the leftView is opened. open var isLeftViewOpened: Bool { - guard nil != leftView else { + guard let v = leftView else { return false } - return leftView!.x != -leftViewWidth + return v.x != -leftViewWidth } /// Indicates if the rightView is opened. open var isRightViewOpened: Bool { - guard nil != rightView else { + guard let v = rightView else { return false } - return rightView!.x != Screen.width + return v.x != Screen.width } /** @@ -372,14 +367,14 @@ open class NavigationDrawerController: RootController { opens up to. */ @IBInspectable - open fileprivate(set) var leftViewWidth: CGFloat! + open fileprivate(set) var leftViewWidth: CGFloat = 0 /** A CGFloat property to access the width that the rightView opens up to. */ @IBInspectable - open fileprivate(set) var rightViewWidth: CGFloat! + open fileprivate(set) var rightViewWidth: CGFloat = 0 /** An initializer that initializes the object with a NSCoder object. @@ -413,8 +408,8 @@ open class NavigationDrawerController: RootController { prepare() } - open override func transition(to viewController: UIViewController, duration: TimeInterval = 0.5, options: UIViewAnimationOptions = [], animations: (() -> Void)? = nil, completion: ((Bool) -> Void)? = nil) { - super.transition(to: viewController, duration: duration, options: options, animations: animations) { [weak self, completion = completion] (result) in + open override func transition(to viewController: UIViewController, completion: ((Bool) -> Void)? = nil) { + super.transition(to: viewController) { [weak self, completion = completion] (result) in guard let s = self else { return } @@ -434,9 +429,9 @@ open class NavigationDrawerController: RootController { v.height = view.bounds.height leftViewThreshold = leftViewWidth / 2 if let vc = leftViewController { - vc.view.width = v.width - vc.view.height = v.height - vc.view.center = CGPoint(x: v.width / 2, y: v.height / 2) + vc.view.width = leftViewWidth + vc.view.height = v.bounds.height + vc.view.center = CGPoint(x: leftViewWidth / 2, y: v.bounds.height / 2) } } @@ -445,11 +440,13 @@ open class NavigationDrawerController: RootController { v.height = view.bounds.height rightViewThreshold = view.bounds.width - rightViewWidth / 2 if let vc = rightViewController { - vc.view.width = v.width - vc.view.height = v.height - vc.view.center = CGPoint(x: v.width / 2, y: v.height / 2) + vc.view.width = rightViewWidth + vc.view.height = v.bounds.height + vc.view.center = CGPoint(x: rightViewWidth / 2, y: v.bounds.height / 2) } } + + rootViewController.view.frame = container.bounds } open override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { @@ -459,16 +456,9 @@ open class NavigationDrawerController: RootController { return } - v.position.x = size.width + (isRightViewOpened ? -v.width : v.width) / 2 + v.position.x = size.width + (isRightViewOpened ? -v.bounds.width : v.bounds.width) / 2 } - /** - Prepares the view instance when intialized. When subclassing, - it is recommended to override the prepare method - to initialize property values and other setup operations. - The super.prepare method should always be called immediately - when subclassing. - */ open override func prepare() { super.prepare() prepareContentViewController() @@ -504,49 +494,56 @@ open class NavigationDrawerController: RootController { if hide { UIView.animate(withDuration: duration, - animations: { [weak self] in - if let s = self { - v.bounds.size.width = width - v.position.x = -width / 2 - s.rootViewController.view.alpha = 1 + animations: { [weak self, v = v] in + guard let s = self else { + return } - }) { [weak self] _ in - if let s = self { - v.isShadowPathAutoSizing = true - s.layoutSubviews() - s.hideView(container: v) + + v.bounds.size.width = width + v.position.x = -width / 2 + s.rootViewController.view.alpha = 1 + }) { [weak self, v = v] _ in + guard let s = self else { + return } + + v.isShadowPathAutoSizing = true + s.layoutSubviews() + s.hideView(container: v) } } else { UIView.animate(withDuration: duration, - animations: { [weak self] in - if let s = self { - v.bounds.size.width = width - v.position.x = width / 2 - s.rootViewController.view.alpha = 0.5 + animations: { [weak self, v = v] in + guard let s = self else { + return } - }) { [weak self] _ in - if let s = self { - v.isShadowPathAutoSizing = true - s.layoutSubviews() - s.showView(container: v) + + v.bounds.size.width = width + v.position.x = width / 2 + s.rootViewController.view.alpha = 0.5 + }) { [weak self, v = v] _ in + guard let s = self else { + return } + + v.isShadowPathAutoSizing = true + s.layoutSubviews() + s.showView(container: v) } } } else { v.bounds.size.width = width + if hide { hideView(container: v) - v.position.x = -v.width / 2 + v.position.x = -v.bounds.width / 2 rootViewController.view.alpha = 1 } else { - v.isShadowPathAutoSizing = false - showView(container: v) v.position.x = width / 2 rootViewController.view.alpha = 0.5 - v.isShadowPathAutoSizing = true } + layoutSubviews() } } @@ -579,49 +576,56 @@ open class NavigationDrawerController: RootController { if hide { UIView.animate(withDuration: duration, - animations: { [weak self] in - if let s = self { - v.bounds.size.width = width - v.position.x = s.view.bounds.width + width / 2 - s.rootViewController.view.alpha = 1 + animations: { [weak self, v = v] in + guard let s = self else { + return } - }) { [weak self] _ in - if let s = self { - v.isShadowPathAutoSizing = true - s.layoutSubviews() - s.hideView(container: v) + + v.bounds.size.width = width + v.position.x = s.view.bounds.width + width / 2 + s.rootViewController.view.alpha = 1 + }) { [weak self, v = v] _ in + guard let s = self else { + return } + + v.isShadowPathAutoSizing = true + s.layoutSubviews() + s.hideView(container: v) } } else { UIView.animate(withDuration: duration, - animations: { [weak self] in - if let s = self { - v.bounds.size.width = width - v.position.x = s.view.bounds.width - width / 2 - s.rootViewController.view.alpha = 0.5 + animations: { [weak self, v = v] in + guard let s = self else { + return } - }) { [weak self] _ in - if let s = self { - v.isShadowPathAutoSizing = true - s.layoutSubviews() - s.showView(container: v) + + v.bounds.size.width = width + v.position.x = s.view.bounds.width - width / 2 + s.rootViewController.view.alpha = 0.5 + }) { [weak self, v = v] _ in + guard let s = self else { + return } + + v.isShadowPathAutoSizing = true + s.layoutSubviews() + s.showView(container: v) } } } else { v.bounds.size.width = width + if hide { hideView(container: v) - v.position.x = view.bounds.width + v.width / 2 + v.position.x = view.bounds.width + v.bounds.width / 2 rootViewController.view.alpha = 1 } else { - v.isShadowPathAutoSizing = false - showView(container: v) v.position.x = view.bounds.width - width / 2 rootViewController.view.alpha = 0.5 - v.isShadowPathAutoSizing = true } + layoutSubviews() } } @@ -676,7 +680,7 @@ open class NavigationDrawerController: RootController { return } - v.position.x = v.width / 2 + v.position.x = v.bounds.width / 2 s.rootViewController.view.alpha = 0.5 }) { [weak self] _ in guard let s = self else { @@ -715,7 +719,7 @@ open class NavigationDrawerController: RootController { return } - v.position.x = s.view.bounds.width - v.width / 2 + v.position.x = s.view.bounds.width - v.bounds.width / 2 s.rootViewController.view.alpha = 0.5 }) { [weak self] _ in guard let s = self else { @@ -751,9 +755,9 @@ open class NavigationDrawerController: RootController { return } - v.position.x = -v.width / 2 + v.position.x = -v.bounds.width / 2 s.rootViewController.view.alpha = 1 - }) { [weak self] _ in + }) { [weak self, v = v] _ in guard let s = self else { return } @@ -790,9 +794,9 @@ open class NavigationDrawerController: RootController { return } - v.position.x = s.view.bounds.width + v.width / 2 + v.position.x = s.view.bounds.width + v.bounds.width / 2 s.rootViewController.view.alpha = 1 - }) { [weak self] _ in + }) { [weak self, v = v] _ in guard let s = self else { return } @@ -967,7 +971,7 @@ extension NavigationDrawerController { /// Prepares the contentViewController. fileprivate func prepareContentViewController() { contentViewController.view.backgroundColor = .black - prepare(viewController: contentViewController, withContainer: view) + prepare(viewController: contentViewController, in: view) view.sendSubview(toBack: contentViewController.view) } @@ -977,7 +981,7 @@ extension NavigationDrawerController { return } - prepare(viewController: leftViewController, withContainer: v) + prepare(viewController: leftViewController, in: v) } /// A method that prepares the rightViewController. @@ -986,7 +990,7 @@ extension NavigationDrawerController { return } - prepare(viewController: rightViewController, withContainer: v) + prepare(viewController: rightViewController, in: v) } /// A method that prepares the leftView. @@ -999,7 +1003,7 @@ extension NavigationDrawerController { leftViewWidth = .phone == Device.userInterfaceIdiom ? 280 : 320 leftView = UIView() - leftView!.frame = CGRect(x: 0, y: 0, width: leftViewWidth, height: view.height) + leftView!.frame = CGRect(x: 0, y: 0, width: leftViewWidth, height: view.bounds.height) leftView!.backgroundColor = nil view.addSubview(leftView!) @@ -1019,7 +1023,7 @@ extension NavigationDrawerController { rightViewWidth = .phone == Device.userInterfaceIdiom ? 280 : 320 rightView = UIView() - rightView!.frame = CGRect(x: view.width, y: 0, width: rightViewWidth, height: view.height) + rightView!.frame = CGRect(x: view.bounds.width, y: 0, width: rightViewWidth, height: view.bounds.height) rightView!.backgroundColor = nil view.addSubview(rightView!) @@ -1037,6 +1041,7 @@ extension NavigationDrawerController { leftPanGesture = UIPanGestureRecognizer(target: self, action: #selector(handleLeftViewPanGesture(recognizer:))) leftPanGesture!.delegate = self + leftPanGesture!.cancelsTouchesInView = false view.addGestureRecognizer(leftPanGesture!) } @@ -1060,6 +1065,7 @@ extension NavigationDrawerController { rightPanGesture = UIPanGestureRecognizer(target: self, action: #selector(handleRightViewPanGesture(recognizer:))) rightPanGesture!.delegate = self + rightPanGesture!.cancelsTouchesInView = false view.addGestureRecognizer(rightPanGesture!) } @@ -1088,15 +1094,19 @@ extension NavigationDrawerController: UIGestureRecognizerDelegate { if !isRightViewOpened && gestureRecognizer == leftPanGesture && (isLeftViewOpened || isPointContainedWithinLeftThreshold(point: touch.location(in: view))) { return true } + if !isLeftViewOpened && gestureRecognizer == rightPanGesture && (isRightViewOpened || isPointContainedWithinRighThreshold(point: touch.location(in: view))) { return true } + if isLeftViewOpened && gestureRecognizer == leftTapGesture { return true } + if isRightViewOpened && gestureRecognizer == rightTapGesture { return true } + return false } @@ -1108,47 +1118,49 @@ extension NavigationDrawerController: UIGestureRecognizerDelegate { */ @objc fileprivate func handleLeftViewPanGesture(recognizer: UIPanGestureRecognizer) { - if isLeftViewEnabled && (isLeftViewOpened || !isRightViewOpened && isPointContainedWithinLeftThreshold(point: recognizer.location(in: view))) { - guard let v = leftView else { - return + guard isLeftViewEnabled && (isLeftViewOpened || !isRightViewOpened && isPointContainedWithinLeftThreshold(point: recognizer.location(in: view))) else { + return + } + + guard let v = leftView else { + return + } + + let point = recognizer.location(in: view) + + // Animate the panel. + switch recognizer.state { + case .began: + originalX = v.position.x + showView(container: v) + + delegate?.navigationDrawerController?(navigationDrawerController: self, didBeginPanAt: point, position: .left) + case .changed: + let w = v.bounds.width + let translationX = recognizer.translation(in: v).x + + v.position.x = originalX + translationX > (w / 2) ? (w / 2) : originalX + translationX + + let a = 1 - v.position.x / v.bounds.width + rootViewController.view.alpha = 0.5 < a && v.position.x <= v.bounds.width / 2 ? a : 0.5 + + if translationX >= leftThreshold { + hideStatusBar() } - let point = recognizer.location(in: view) + delegate?.navigationDrawerController?(navigationDrawerController: self, didChangePanAt: point, position: .left) + case .ended, .cancelled, .failed: + let p = recognizer.velocity(in: recognizer.view) + let x = p.x >= 500 || p.x <= -500 ? p.x : 0 - // Animate the panel. - switch recognizer.state { - case .began: - originalX = v.position.x - showView(container: v) - - delegate?.navigationDrawerController?(navigationDrawerController: self, didBeginPanAt: point, position: .left) - case .changed: - let w = v.width - let translationX = recognizer.translation(in: v).x - - v.position.x = originalX + translationX > (w / 2) ? (w / 2) : originalX + translationX - - let a = 1 - v.position.x / v.width - rootViewController.view.alpha = 0.5 < a && v.position.x <= v.width / 2 ? a : 0.5 - - if translationX >= leftThreshold { - hideStatusBar() - } - - delegate?.navigationDrawerController?(navigationDrawerController: self, didChangePanAt: point, position: .left) - case .ended, .cancelled, .failed: - let p = recognizer.velocity(in: recognizer.view) - let x = p.x >= 1000 || p.x <= -1000 ? p.x : 0 - - delegate?.navigationDrawerController?(navigationDrawerController: self, didEndPanAt: point, position: .left) - - if v.x <= -leftViewWidth + leftViewThreshold || x < -1000 { - closeLeftView(velocity: x) - } else { - openLeftView(velocity: x) - } - case .possible:break + delegate?.navigationDrawerController?(navigationDrawerController: self, didEndPanAt: point, position: .left) + + if v.x <= -leftViewWidth + leftViewThreshold || x < -500 { + closeLeftView(velocity: x) + } else { + openLeftView(velocity: x) } + case .possible:break } } @@ -1160,47 +1172,49 @@ extension NavigationDrawerController: UIGestureRecognizerDelegate { */ @objc fileprivate func handleRightViewPanGesture(recognizer: UIPanGestureRecognizer) { - if isRightViewEnabled && (isRightViewOpened || !isLeftViewOpened && isPointContainedWithinRighThreshold(point: recognizer.location(in: view))) { - guard let v = rightView else { - return + guard isRightViewEnabled && (isRightViewOpened || !isLeftViewOpened && isPointContainedWithinRighThreshold(point: recognizer.location(in: view))) else { + return + } + + guard let v = rightView else { + return + } + + let point = recognizer.location(in: view) + + // Animate the panel. + switch recognizer.state { + case .began: + originalX = v.position.x + showView(container: v) + + delegate?.navigationDrawerController?(navigationDrawerController: self, didBeginPanAt: point, position: .right) + case .changed: + let w = v.bounds.width + let translationX = recognizer.translation(in: v).x + + v.position.x = originalX + translationX < view.bounds.width - (w / 2) ? view.bounds.width - (w / 2) : originalX + translationX + + let a = 1 - (view.bounds.width - v.position.x) / v.bounds.width + rootViewController.view.alpha = 0.5 < a && v.position.x >= v.bounds.width / 2 ? a : 0.5 + + if translationX <= -rightThreshold { + hideStatusBar() } - let point = recognizer.location(in: view) + delegate?.navigationDrawerController?(navigationDrawerController: self, didChangePanAt: point, position: .right) + case .ended, .cancelled, .failed: + let p = recognizer.velocity(in: recognizer.view) + let x = p.x >= 1000 || p.x <= -1000 ? p.x : 0 - // Animate the panel. - switch recognizer.state { - case .began: - originalX = v.position.x - showView(container: v) - - delegate?.navigationDrawerController?(navigationDrawerController: self, didBeginPanAt: point, position: .right) - case .changed: - let w = v.width - let translationX = recognizer.translation(in: v).x - - v.position.x = originalX + translationX < view.bounds.width - (w / 2) ? view.bounds.width - (w / 2) : originalX + translationX - - let a = 1 - (view.bounds.width - v.position.x) / v.width - rootViewController.view.alpha = 0.5 < a && v.position.x >= v.width / 2 ? a : 0.5 - - if translationX <= -rightThreshold { - hideStatusBar() - } - - delegate?.navigationDrawerController?(navigationDrawerController: self, didChangePanAt: point, position: .right) - case .ended, .cancelled, .failed: - let p = recognizer.velocity(in: recognizer.view) - let x = p.x >= 1000 || p.x <= -1000 ? p.x : 0 - - delegate?.navigationDrawerController?(navigationDrawerController: self, didEndPanAt: point, position: .right) - - if v.x >= rightViewThreshold || x > 1000 { - closeRightView(velocity: x) - } else { - openRightView(velocity: x) - } - case .possible:break + delegate?.navigationDrawerController?(navigationDrawerController: self, didEndPanAt: point, position: .right) + + if v.x >= rightViewThreshold || x > 1000 { + closeRightView(velocity: x) + } else { + openRightView(velocity: x) } + case .possible:break } } @@ -1222,9 +1236,11 @@ extension NavigationDrawerController: UIGestureRecognizerDelegate { delegate?.navigationDrawerController?(navigationDrawerController: self, didTapAt: recognizer.location(in: view), position: .left) - if isLeftViewEnabled && isLeftViewOpened && !isPointContainedWithinView(container: v, point: recognizer.location(in: v)) { - closeLeftView() + guard isLeftViewEnabled && isLeftViewOpened && !isPointContainedWithinView(container: v, point: recognizer.location(in: v)) else { + return } + + closeLeftView() } /** @@ -1245,8 +1261,10 @@ extension NavigationDrawerController: UIGestureRecognizerDelegate { delegate?.navigationDrawerController?(navigationDrawerController: self, didTapAt: recognizer.location(in: view), position: .right) - if isRightViewEnabled && isRightViewOpened && !isPointContainedWithinView(container: v, point: recognizer.location(in: v)) { - closeRightView() + guard isRightViewEnabled && isRightViewOpened && !isPointContainedWithinView(container: v, point: recognizer.location(in: v)) else { + return } + + closeRightView() } } diff --git a/Example/Pods/Material/Sources/iOS/NavigationItem.swift b/Example/Pods/Material/Sources/iOS/NavigationItem.swift index 8783996..9cc4936 100644 --- a/Example/Pods/Material/Sources/iOS/NavigationItem.swift +++ b/Example/Pods/Material/Sources/iOS/NavigationItem.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,8 +31,8 @@ import UIKit /// A memory reference to the NavigationItem instance. -private var NavigationItemKey: UInt8 = 0 -private var NavigationItemContext: UInt8 = 0 +fileprivate var NavigationItemKey: UInt8 = 0 +fileprivate var NavigationItemContext: UInt8 = 0 public class NavigationItem: NSObject { /// Should center the contentView. @@ -43,16 +43,16 @@ public class NavigationItem: NSObject { } /// Back Button. - public private(set) lazy var backButton: IconButton = IconButton() + public fileprivate(set) lazy var backButton: IconButton = IconButton() /// Content View. - public private(set) lazy var contentView = UIView() + public fileprivate(set) var contentView = UIView() /// Title label. - public private(set) lazy var titleLabel = UILabel() + public fileprivate(set) var titleLabel = UILabel() /// Detail label. - public private(set) lazy var detailLabel = UILabel() + public fileprivate(set) var detailLabel = UILabel() /// Left items. public var leftViews = [UIView]() { @@ -84,8 +84,16 @@ public class NavigationItem: NSObject { } } + /// An optional reference to the NavigationBar. public var navigationBar: NavigationBar? { - return contentView.superview?.superview as? NavigationBar + var v = contentView.superview + while nil != v { + if let navigationBar = v as? NavigationBar { + return navigationBar + } + v = v?.superview + } + return nil } open override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { @@ -108,12 +116,12 @@ public class NavigationItem: NSObject { } /// Reloads the subviews for the NavigationBar. - internal func reload() { + fileprivate func reload() { navigationBar?.layoutSubviews() } /// Prepares the titleLabel. - private func prepareTitleLabel() { + fileprivate func prepareTitleLabel() { titleLabel.textAlignment = .center titleLabel.contentScaleFactor = Screen.scale titleLabel.font = RobotoFont.medium(with: 17) @@ -122,7 +130,7 @@ public class NavigationItem: NSObject { } /// Prepares the detailLabel. - private func prepareDetailLabel() { + fileprivate func prepareDetailLabel() { detailLabel.textAlignment = .center titleLabel.contentScaleFactor = Screen.scale detailLabel.font = RobotoFont.regular(with: 12) @@ -134,17 +142,17 @@ extension UINavigationItem { /// NavigationItem reference. public internal(set) var navigationItem: NavigationItem { get { - return AssociatedObject(base: self, key: &NavigationItemKey) { + return AssociatedObject.get(base: self, key: &NavigationItemKey) { return NavigationItem() } } set(value) { - AssociateObject(base: self, key: &NavigationItemKey, value: value) + AssociatedObject.set(base: self, key: &NavigationItemKey, value: value) } } /// Should center the contentView. - public var contentViewAlignment: ContentViewAlignment { + open var contentViewAlignment: ContentViewAlignment { get { return navigationItem.contentViewAlignment } @@ -154,18 +162,18 @@ extension UINavigationItem { } /// Content View. - public var contentView: UIView { + open var contentView: UIView { return navigationItem.contentView } /// Back Button. - public var backButton: IconButton { + open var backButton: IconButton { return navigationItem.backButton } /// Title text. @nonobjc - public var title: String? { + open var title: String? { get { return titleLabel.text } @@ -176,12 +184,12 @@ extension UINavigationItem { } /// Title Label. - public var titleLabel: UILabel { + open var titleLabel: UILabel { return navigationItem.titleLabel } /// Detail text. - public var detail: String? { + open var detail: String? { get { return detailLabel.text } @@ -192,12 +200,12 @@ extension UINavigationItem { } /// Detail Label. - public var detailLabel: UILabel { + open var detailLabel: UILabel { return navigationItem.detailLabel } /// Left side UIViews. - public var leftViews: [UIView] { + open var leftViews: [UIView] { get { return navigationItem.leftViews } @@ -207,7 +215,7 @@ extension UINavigationItem { } /// Right side UIViews. - public var rightViews: [UIView] { + open var rightViews: [UIView] { get { return navigationItem.rightViews } diff --git a/Example/Pods/Material/Sources/iOS/Offset.swift b/Example/Pods/Material/Sources/iOS/Offset.swift index 9f3d085..3cd09d2 100644 --- a/Example/Pods/Material/Sources/iOS/Offset.swift +++ b/Example/Pods/Material/Sources/iOS/Offset.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/Example/Pods/Material/Sources/iOS/PageTabBarController.swift b/Example/Pods/Material/Sources/iOS/PageTabBarController.swift deleted file mode 100644 index 89c160b..0000000 --- a/Example/Pods/Material/Sources/iOS/PageTabBarController.swift +++ /dev/null @@ -1,355 +0,0 @@ -/* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, 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 of CosmicMind 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. - */ - -import UIKit - -/// A memory reference to the PageTabBarItem instance for UIViewController extensions. -private var PageTabBarItemKey: UInt8 = 0 - -open class PageTabBarItem: FlatButton { - open override func prepare() { - super.prepare() - pulseAnimation = .none - } -} - -open class PageTabBar: TabBar { - open override func prepare() { - super.prepare() - isLineAnimated = false - lineAlignment = .top - } -} - -@objc(PageTabBarAlignment) -public enum PageTabBarAlignment: Int { - case top - case bottom -} - -/// Grid extension for UIView. -extension UIViewController { - /// Grid reference. - public private(set) var pageTabBarItem: PageTabBarItem { - get { - return AssociatedObject(base: self, key: &PageTabBarItemKey) { - return PageTabBarItem() - } - } - set(value) { - AssociateObject(base: self, key: &PageTabBarItemKey, value: value) - } - } -} - -extension UIViewController { - /** - A convenience property that provides access to the PageTabBarController. - This is the recommended method of accessing the PageTabBarController - through child UIViewControllers. - */ - public var pageTabBarController: PageTabBarController? { - var viewController: UIViewController? = self - while nil != viewController { - if viewController is PageTabBarController { - return viewController as? PageTabBarController - } - viewController = viewController?.parent - } - return nil - } -} - -@objc(PageTabBarControllerDelegate) -public protocol PageTabBarControllerDelegate { - /** - A delegation method that is executed when a UIViewController did transition to. - - Parameter pageTabBarController: A PageTabBarController. - - Parameter willTransitionTo viewController: A UIViewController. - */ - @objc - optional func pageTabBarController(pageTabBarController: PageTabBarController, didTransitionTo viewController: UIViewController) -} - -@objc(PageTabBarController) -open class PageTabBarController: RootController { - /// Reference to the PageTabBar. - @IBInspectable - open let pageTabBar = PageTabBar() - - /// A boolean that indicates whether bounce is enabled. - open var isBounceEnabled: Bool { - didSet { - scrollView?.bounces = isBounceEnabled - } - } - - /// Indicates that the tab has been pressed and animating. - open internal(set) var isTabSelectedAnimation = false - - /// The currently selected UIViewController. - open internal(set) var selectedIndex = 0 - - /// PageTabBar alignment setting. - open var pageTabBarAlignment = PageTabBarAlignment.bottom - - /// Delegation handler. - open weak var delegate: PageTabBarControllerDelegate? - - /// A reference to the instance when it is a UIPageViewController. - open var pageViewController: UIPageViewController? { - return rootViewController as? UIPageViewController - } - - /// A reference to the scrollView. - open var scrollView: UIScrollView? { - guard let v = pageViewController else { - return nil - } - - for view in v.view.subviews { - if let v = view as? UIScrollView { - return v - } - } - - return nil - } - - /// A reference to the UIViewControllers. - open var viewControllers = [UIViewController]() - - public required init?(coder aDecoder: NSCoder) { - isBounceEnabled = true - super.init(coder: aDecoder) - prepare() - } - - public override init(rootViewController: UIViewController) { - isBounceEnabled = true - super.init(rootViewController: UIPageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)) - viewControllers.append(rootViewController) - setViewControllers(viewControllers, direction: .forward, animated: true) - prepare() - } - - public init(viewControllers: [UIViewController], selectedIndex: Int = 0) { - isBounceEnabled = true - super.init(rootViewController: UIPageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal, options: nil)) - self.selectedIndex = selectedIndex - self.viewControllers.append(contentsOf: viewControllers) - setViewControllers([self.viewControllers[selectedIndex]], direction: .forward, animated: true) - prepare() - } - - open override func layoutSubviews() { - super.layoutSubviews() - - let p = pageTabBar.intrinsicContentSize.height + pageTabBar.layoutEdgeInsets.top + pageTabBar.layoutEdgeInsets.bottom - let y = view.height - p - - pageTabBar.height = p - pageTabBar.width = view.width + pageTabBar.layoutEdgeInsets.left + pageTabBar.layoutEdgeInsets.right - - rootViewController.view.height = y - - switch pageTabBarAlignment { - case .top: - pageTabBar.y = 0 - rootViewController.view.y = p - case .bottom: - pageTabBar.y = y - rootViewController.view.y = 0 - } - } - - /** - Sets the view controllers. - - Parameter _ viewController: An Array of UIViewControllers. - - Parameter direction: A UIPageViewControllerNavigationDirection enum value. - - Parameter animated: A boolean indicating to include animation. - - Parameter completion: An optional completion block. - */ - open func setViewControllers(_ viewControllers: [UIViewController], direction: UIPageViewControllerNavigationDirection, animated: Bool, completion: ((Bool) -> Void)? = nil) { - pageViewController?.setViewControllers(viewControllers, direction: direction, animated: animated, completion: completion) - prepare() - } - - /** - Prepares the view instance when intialized. When subclassing, - it is recommended to override the prepare method - to initialize property values and other setup operations. - The super.prepare method should always be called immediately - when subclassing. - */ - open override func prepare() { - super.prepare() - preparePageTabBar() - preparePageTabBarItems() - } - - open override func prepareRootViewController() { - super.prepareRootViewController() - - guard let v = pageViewController else { - return - } - - v.delegate = self - v.dataSource = self - v.isDoubleSided = false - - scrollView?.delegate = self - } - - /// Prepares the pageTabBarItems. - open func preparePageTabBarItems() { - pageTabBar.buttons.removeAll() - - for x in viewControllers { - let button = x.pageTabBarItem as UIButton - pageTabBar.buttons.append(button) - button.removeTarget(self, action: #selector(pageTabBar.handleButton(button:)), for: .touchUpInside) - button.removeTarget(self, action: #selector(handlePageTabBarButton(button:)), for: .touchUpInside) - button.addTarget(self, action: #selector(handlePageTabBarButton(button:)), for: .touchUpInside) - } - } - - /** - Handles the pageTabBarButton. - - Parameter button: A UIButton. - */ - @objc - internal func handlePageTabBarButton(button: UIButton) { - guard let index = pageTabBar.buttons.index(of: button) else { - return - } - - guard index != selectedIndex else { - return - } - - let direction: UIPageViewControllerNavigationDirection = index < selectedIndex ? .reverse : .forward - - isTabSelectedAnimation = true - selectedIndex = index - - pageTabBar.select(at: selectedIndex) - - setViewControllers([viewControllers[index]], direction: direction, animated: true) { [weak self] _ in - guard let s = self else { - return - } - s.isTabSelectedAnimation = false - s.delegate?.pageTabBarController?(pageTabBarController: s, didTransitionTo: s.viewControllers[s.selectedIndex]) - } - } - - /// Prepares the pageTabBar. - private func preparePageTabBar() { - pageTabBar.zPosition = 1000 - pageTabBar.dividerColor = Color.grey.lighten3 - view.addSubview(pageTabBar) - pageTabBar.select(at: selectedIndex) - } -} - -extension PageTabBarController: UIPageViewControllerDelegate { - open func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) { - guard let v = pageViewController.viewControllers?.first else { - return - } - - guard let index = viewControllers.index(of: v) else { - return - } - - selectedIndex = index - pageTabBar.select(at: selectedIndex) - - if finished && completed { - delegate?.pageTabBarController?(pageTabBarController: self, didTransitionTo: v) - } - } -} - -extension PageTabBarController: UIPageViewControllerDataSource { - open func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? { - guard let current = viewControllers.index(of: viewController) else { - return nil - } - - let previous = current - 1 - - guard previous >= 0 else { - return nil - } - - return viewControllers[previous] - } - - open func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? { - guard let current = viewControllers.index(of: viewController) else { - return nil - } - - let next = current + 1 - - guard viewControllers.count > next else { - return nil - } - - return viewControllers[next] - } -} - -extension PageTabBarController: UIScrollViewDelegate { - open func scrollViewDidScroll(_ scrollView: UIScrollView) { - guard !pageTabBar.isAnimating else { - return - } - - guard !isTabSelectedAnimation else { - return - } - - guard let selected = pageTabBar.selected else { - return - } - - guard 0 < view.width else { - return - } - - let x = (scrollView.contentOffset.x - view.width) / scrollView.contentSize.width * view.width - - pageTabBar.line.center.x = selected.center.x + x - } -} diff --git a/Example/Pods/Material/Sources/iOS/PresenterCard.swift b/Example/Pods/Material/Sources/iOS/PresenterCard.swift index db83b52..a3e92e6 100644 --- a/Example/Pods/Material/Sources/iOS/PresenterCard.swift +++ b/Example/Pods/Material/Sources/iOS/PresenterCard.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -79,6 +79,6 @@ open class PresenterCard: Card { } container.height = h - height = h + bounds.size.height = h } } diff --git a/Example/Pods/Material/Sources/iOS/MotionPulse.swift b/Example/Pods/Material/Sources/iOS/PulseAnimation.swift similarity index 82% rename from Example/Pods/Material/Sources/iOS/MotionPulse.swift rename to Example/Pods/Material/Sources/iOS/PulseAnimation.swift index 6b830ab..7bc406b 100644 --- a/Example/Pods/Material/Sources/iOS/MotionPulse.swift +++ b/Example/Pods/Material/Sources/iOS/PulseAnimation.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -53,12 +53,17 @@ public protocol Pulseable { var pulseOpacity: CGFloat { get set } } +internal protocol PulseableLayer { + /// A reference to the pulse layer. + var pulseLayer: CALayer? { get } +} + public struct Pulse { /// A UIView that is Pulseable. fileprivate weak var pulseView: UIView? /// The layer the pulse layers are added to. - fileprivate weak var pulseLayer: CALayer? + internal weak var pulseLayer: CALayer? /// Pulse layers. fileprivate var layers = [CAShapeLayer]() @@ -77,7 +82,7 @@ public struct Pulse { - Parameter pulseView: An optional UIView. - Parameter pulseLayer: An optional CALayer. */ - internal init(pulseView: UIView?, pulseLayer: CALayer?) { + public init(pulseView: UIView?, pulseLayer: CALayer?) { self.pulseView = pulseView self.pulseLayer = pulseLayer } @@ -86,7 +91,7 @@ public struct Pulse { Triggers the expanding animation. - Parameter point: A point to pulse from. */ - public mutating func expandAnimation(point: CGPoint) { + public mutating func expand(point: CGPoint) { guard let view = pulseView else { return } @@ -114,7 +119,7 @@ public struct Pulse { let w = view.bounds.width let h = view.bounds.height - Motion.disable(animations: { [ + Motion.disable({ [ n = .center == animation ? w < h ? w : h : w < h ? h : w, bounds = layer.bounds, animation = animation, @@ -123,7 +128,7 @@ public struct Pulse { ] in bLayer.frame = bounds - pLayer.bounds = CGRect(x: 0, y: 0, width: n, height: n) + pLayer.frame = CGRect(x: 0, y: 0, width: n, height: n) switch animation { case .center, .centerWithBacking, .centerRadialBeyondBounds: @@ -139,27 +144,27 @@ public struct Pulse { bLayer.setValue(false, forKey: "animated") - let duration: CFTimeInterval = .center == animation ? 0.16125 : 0.325 + let t: TimeInterval = .center == animation ? 0.16125 : 0.325 switch animation { case .centerWithBacking, .backing, .pointWithBacking: - bLayer.add(Motion.backgroundColor(color: color.withAlphaComponent(opacity / 2), duration: duration), forKey: nil) + bLayer.animate(.background(color: color.withAlphaComponent(opacity / 2)), .duration(t)) default:break } switch animation { case .center, .centerWithBacking, .centerRadialBeyondBounds, .radialBeyondBounds, .point, .pointWithBacking: - pLayer.add(Motion.scale(by: 1, duration: duration), forKey: nil) + pLayer.animate(.scale(1), .duration(t)) default:break } - Motion.delay(time: duration) { + Motion.delay(t) { bLayer.setValue(true, forKey: "animated") } } /// Triggers the contracting animation. - public mutating func contractAnimation() { + public mutating func contract() { guard let bLayer = layers.popLast() else { return } @@ -168,29 +173,26 @@ public struct Pulse { return } - Motion.delay(time: animated ? 0 : 0.15) { [animation = animation, color = color] in + Motion.delay(animated ? 0 : 0.15) { [animation = animation, color = color] in guard let pLayer = bLayer.sublayers?.first as? CAShapeLayer else { return } - let duration = 0.325 + let t: TimeInterval = 0.325 switch animation { case .centerWithBacking, .backing, .pointWithBacking: - bLayer.add(Motion.backgroundColor(color: color.withAlphaComponent(0), duration: duration), forKey: nil) + bLayer.animate(.background(color: color.withAlphaComponent(0)), .duration(t)) default:break } switch animation { case .center, .centerWithBacking, .centerRadialBeyondBounds, .radialBeyondBounds, .point, .pointWithBacking: - pLayer.add(Motion.animate(group: [ - Motion.scale(by: .center == animation ? 1 : 1.325), - Motion.backgroundColor(color: color.withAlphaComponent(0)) - ], duration: duration), forKey: nil) + pLayer.animate(.background(color: color.withAlphaComponent(0))) default:break } - Motion.delay(time: duration) { + Motion.delay(t) { pLayer.removeFromSuperlayer() bLayer.removeFromSuperlayer() } diff --git a/Example/Pods/Material/Sources/iOS/PulseView.swift b/Example/Pods/Material/Sources/iOS/PulseView.swift index 9edc50f..0729a3d 100644 --- a/Example/Pods/Material/Sources/iOS/PulseView.swift +++ b/Example/Pods/Material/Sources/iOS/PulseView.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,9 +30,14 @@ import UIKit -open class PulseView: View, Pulseable { +open class PulseView: View, Pulseable, PulseableLayer { /// A Pulse reference. - fileprivate var pulse: Pulse! + internal var pulse: Pulse! + + /// A reference to the pulse layer. + internal var pulseLayer: CALayer? { + return pulse.pulseLayer + } /// PulseAnimation value. open var pulseAnimation: PulseAnimation { @@ -72,11 +77,9 @@ open class PulseView: View, Pulseable { from the center. */ open func pulse(point: CGPoint? = nil) { - let p = point ?? center - - pulse.expandAnimation(point: p) - Motion.delay(time: 0.35) { [weak self] in - self?.pulse.contractAnimation() + pulse.expand(point: point ?? center) + Motion.delay(0.35) { [weak self] in + self?.pulse.contract() } } @@ -88,7 +91,7 @@ open class PulseView: View, Pulseable { */ open override func touchesBegan(_ touches: Set, with event: UIEvent?) { super.touchesBegan(touches, with: event) - pulse.expandAnimation(point: layer.convert(touches.first!.location(in: self), from: layer)) + pulse.expand(point: layer.convert(touches.first!.location(in: self), from: layer)) } /** @@ -99,7 +102,7 @@ open class PulseView: View, Pulseable { */ open override func touchesEnded(_ touches: Set, with event: UIEvent?) { super.touchesEnded(touches, with: event) - pulse.contractAnimation() + pulse.contract() } /** @@ -110,16 +113,9 @@ open class PulseView: View, Pulseable { */ open override func touchesCancelled(_ touches: Set, with event: UIEvent?) { super.touchesCancelled(touches, with: event) - pulse.contractAnimation() + pulse.contract() } - /** - Prepares the view instance when intialized. When subclassing, - it is recommended to override the prepare method - to initialize property values and other setup operations. - The super.prepare method should always be called immediately - when subclassing. - */ open override func prepare() { super.prepare() preparePulse() diff --git a/Example/Pods/Material/Sources/iOS/RaisedButton.swift b/Example/Pods/Material/Sources/iOS/RaisedButton.swift index 400c1bf..14ab7d7 100644 --- a/Example/Pods/Material/Sources/iOS/RaisedButton.swift +++ b/Example/Pods/Material/Sources/iOS/RaisedButton.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,13 +31,6 @@ import UIKit open class RaisedButton: Button { - /** - Prepares the view instance when intialized. When subclassing, - it is recommended to override the prepare method - to initialize property values and other setup operations. - The super.prepare method should always be called immediately - when subclassing. - */ open override func prepare() { super.prepare() depthPreset = .depth1 diff --git a/Example/Pods/Material/Sources/iOS/RobotoFont.swift b/Example/Pods/Material/Sources/iOS/RobotoFont.swift index 55c39fa..7385d94 100644 --- a/Example/Pods/Material/Sources/iOS/RobotoFont.swift +++ b/Example/Pods/Material/Sources/iOS/RobotoFont.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/Example/Pods/Material/Sources/iOS/Screen.swift b/Example/Pods/Material/Sources/iOS/Screen.swift index a36a49d..2364715 100644 --- a/Example/Pods/Material/Sources/iOS/Screen.swift +++ b/Example/Pods/Material/Sources/iOS/Screen.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/Example/Pods/Material/Sources/iOS/SearchBar.swift b/Example/Pods/Material/Sources/iOS/SearchBar.swift index 36dcc95..6d0ab86 100644 --- a/Example/Pods/Material/Sources/iOS/SearchBar.swift +++ b/Example/Pods/Material/Sources/iOS/SearchBar.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -148,18 +148,11 @@ open class SearchBar: Bar { return } - textField.frame = contentView.bounds + layoutTextField() layoutLeftView() layoutClearButton() } - /** - Prepares the view instance when intialized. When subclassing, - it is recommended to override the prepare method - to initialize property values and other setup operations. - The super.prepare method should always be called immediately - when subclassing. - */ open override func prepare() { super.prepare() prepareTextField() @@ -168,10 +161,9 @@ open class SearchBar: Bar { } extension SearchBar { - /// Layout the clearButton. - open func layoutClearButton() { - let h = textField.frame.height - clearButton.frame = CGRect(x: textField.frame.width - h - 4, y: 4, width: h, height: h - 8) + /// Layout the textField. + open func layoutTextField() { + textField.frame = contentView.bounds } /// Layout the leftView. @@ -185,12 +177,18 @@ extension SearchBar { (v as? UIImageView)?.contentMode = .scaleAspectFit } + + /// Layout the clearButton. + open func layoutClearButton() { + let h = textField.frame.height + clearButton.frame = CGRect(x: textField.frame.width - h - 4, y: 4, width: h, height: h - 8) + } } -extension SearchBar { +fileprivate extension SearchBar { /// Clears the textField text. @objc - fileprivate func handleClearButton() { + func handleClearButton() { guard nil == textField.delegate?.textFieldShouldClear || true == textField.delegate?.textFieldShouldClear?(textField) else { return } @@ -206,27 +204,27 @@ extension SearchBar { // Live updates the search results. @objc - fileprivate func handleEditingChanged(textField: UITextField) { + func handleEditingChanged(textField: UITextField) { delegate?.searchBar?(searchBar: self, didChange: textField, with: textField.text) } } -extension SearchBar { +fileprivate extension SearchBar { /// Prepares the textField. - fileprivate func prepareTextField() { + func prepareTextField() { textField.contentScaleFactor = Screen.scale textField.font = RobotoFont.regular(with: 17) textField.backgroundColor = Color.clear textField.clearButtonMode = .whileEditing + textField.addTarget(self, action: #selector(handleEditingChanged(textField:)), for: .editingChanged) tintColor = placeholderColor textColor = Color.darkText.primary placeholder = "Search" contentView.addSubview(textField) - textField.addTarget(self, action: #selector(handleEditingChanged(textField:)), for: .editingChanged) } /// Prepares the clearButton. - fileprivate func prepareClearButton() { + func prepareClearButton() { clearButton = IconButton(image: Icon.cm.close, tintColor: placeholderColor) clearButton.contentEdgeInsets = .zero isClearButtonAutoHandleEnabled = true diff --git a/Example/Pods/Material/Sources/iOS/SearchBarController.swift b/Example/Pods/Material/Sources/iOS/SearchBarController.swift index 3476280..37c974b 100644 --- a/Example/Pods/Material/Sources/iOS/SearchBarController.swift +++ b/Example/Pods/Material/Sources/iOS/SearchBarController.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,82 +30,93 @@ import UIKit -extension UIViewController { - /** +@objc(SearchBarAlignment) +public enum SearchBarAlignment: Int { + case top + case bottom +} + +public extension UIViewController { + /** A convenience property that provides access to the SearchBarController. This is the recommended method of accessing the SearchBarController through child UIViewControllers. */ - public var searchBarController: SearchBarController? { - var viewController: UIViewController? = self - while nil != viewController { - if viewController is SearchBarController { - return viewController as? SearchBarController - } - viewController = viewController?.parent - } - return nil - } + var searchBarController: SearchBarController? { + return traverseViewControllerHierarchyForClassType() + } } open class SearchBarController: StatusBarController { - /** - A Display value to indicate whether or not to - display the rootViewController to the full view - bounds, or up to the searchBar height. - */ - open var display = Display.partial { + /// Reference to the SearchBar. + @IBInspectable + open let searchBar = SearchBar() + + /// The searchBar alignment. + open var searchBarAlignment = SearchBarAlignment.top { didSet { layoutSubviews() } } - /// Reference to the SearchBar. - @IBInspectable - open let searchBar = SearchBar() - open override func layoutSubviews() { super.layoutSubviews() - - let y = Application.shouldStatusBarBeHidden || statusBar.isHidden ? 0 : statusBar.height - let p = y + searchBar.height - - searchBar.y = y - searchBar.width = view.width - - switch display { - case .partial: - rootViewController.view.y = p - rootViewController.view.height = view.height - p - case .full: - rootViewController.view.frame = view.bounds - } + layoutSearchBar() + layoutContainer() + layoutRootViewController() } - /** - Prepares the view instance when intialized. When subclassing, - it is recommended to override the prepare method - to initialize property values and other setup operations. - The super.prepare method should always be called immediately - when subclassing. - */ open override func prepare() { super.prepare() - prepareStatusBar() - prepareSearchBar() + displayStyle = .partial + + prepareSearchBar() } } -extension SearchBarController { - /// Prepares the statusBar. - fileprivate func prepareStatusBar() { - shouldHideStatusBarOnRotation = false - } - +fileprivate extension SearchBarController { /// Prepares the searchBar. - fileprivate func prepareSearchBar() { - searchBar.depthPreset = .depth1 + func prepareSearchBar() { searchBar.zPosition = 1000 + searchBar.depthPreset = .depth1 view.addSubview(searchBar) } } + +fileprivate extension SearchBarController { + /// Layout the container. + func layoutContainer() { + switch displayStyle { + case .partial: + let p = searchBar.height + let q = statusBarOffsetAdjustment + let h = view.height - p - q + + switch searchBarAlignment { + case .top: + container.y = q + p + container.height = h + case .bottom: + container.y = q + container.height = h + } + + container.width = view.width + + case .full: + container.frame = view.bounds + } + } + + /// Layout the searchBar. + func layoutSearchBar() { + searchBar.x = 0 + searchBar.y = .top == searchBarAlignment ? statusBarOffsetAdjustment : view.height - searchBar.height + searchBar.width = view.width + } + + /// Layout the rootViewController. + func layoutRootViewController() { + rootViewController.view.frame = container.bounds + } +} diff --git a/Example/Pods/Material/Sources/iOS/Shape.swift b/Example/Pods/Material/Sources/iOS/Shape.swift index 8f90323..f048325 100644 --- a/Example/Pods/Material/Sources/iOS/Shape.swift +++ b/Example/Pods/Material/Sources/iOS/Shape.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/Example/Pods/Material/Sources/iOS/Snackbar.swift b/Example/Pods/Material/Sources/iOS/Snackbar.swift index 60d4ed2..f251541 100644 --- a/Example/Pods/Material/Sources/iOS/Snackbar.swift +++ b/Example/Pods/Material/Sources/iOS/Snackbar.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -48,6 +48,17 @@ open class Snackbar: Bar { } } + /// A convenience property to set the titleLabel attributedText. + open var attributedText: NSAttributedString? { + get { + return textLabel.attributedText + } + set(value) { + textLabel.attributedText = value + layoutSubviews() + } + } + /// Text label. @IBInspectable open let textLabel = UILabel() @@ -70,20 +81,15 @@ open class Snackbar: Bar { return super.hitTest(point, with: event) } - /// Reloads the view. - open override func reload() { - super.reload() + open override func layoutSubviews() { + super.layoutSubviews() + guard willLayout else { + return + } centerViews = [textLabel] } - /** - Prepares the view instance when intialized. When subclassing, - it is recommended to override the prepare method - to initialize property values and other setup operations. - The super.prepare method should always be called immediately - when subclassing. - */ open override func prepare() { super.prepare() depthPreset = .none diff --git a/Example/Pods/Material/Sources/iOS/SnackbarController.swift b/Example/Pods/Material/Sources/iOS/SnackbarController.swift index a77d13d..f16d583 100644 --- a/Example/Pods/Material/Sources/iOS/SnackbarController.swift +++ b/Example/Pods/Material/Sources/iOS/SnackbarController.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -78,18 +78,11 @@ extension UIViewController { through child UIViewControllers. */ public var snackbarController: SnackbarController? { - var viewController: UIViewController? = self - while nil != viewController { - if viewController is SnackbarController { - return viewController as? SnackbarController - } - viewController = viewController?.parent - } - return nil + return traverseViewControllerHierarchyForClassType() } } -open class SnackbarController: RootController { +open class SnackbarController: TransitionController { /// Reference to the Snackbar. open let snackbar = Snackbar() @@ -123,7 +116,7 @@ open class SnackbarController: RootController { */ @discardableResult open func animate(snackbar status: SnackbarStatus, delay: TimeInterval = 0, animations: ((Snackbar) -> Void)? = nil, completion: ((Snackbar) -> Void)? = nil) -> MotionDelayCancelBlock? { - return Motion.delay(time: delay) { [weak self, status = status, animations = animations, completion = completion] in + return Motion.delay(delay) { [weak self, status = status, animations = animations, completion = completion] in guard let s = self else { return } @@ -188,13 +181,6 @@ open class SnackbarController: RootController { layoutSnackbar(status: snackbar.status) } - /** - Prepares the view instance when intialized. When subclassing, - it is recommended to override the prepare method - to initialize property values and other setup operations. - The super.prepare method should always be called immediately - when subclassing. - */ open override func prepare() { super.prepare() prepareSnackbar() diff --git a/Example/Pods/Material/Sources/iOS/SpringAnimation.swift b/Example/Pods/Material/Sources/iOS/SpringAnimation.swift new file mode 100644 index 0000000..555f051 --- /dev/null +++ b/Example/Pods/Material/Sources/iOS/SpringAnimation.swift @@ -0,0 +1,477 @@ +/* + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, 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 of CosmicMind 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. + */ + +import UIKit + +@objc(SpringDirection) +public enum SpringDirection: Int { + case up + case down + case left + case right +} + +open class SpringAnimation { + /// A SpringDirection value. + open var springDirection = SpringDirection.up + + /// A Boolean that indicates if the menu is open or not. + open var isOpened = false + + /// Enables the animations for the Menu. + open var isEnabled = true + + /// A preset wrapper around interimSpace. + open var interimSpacePreset = InterimSpacePreset.none { + didSet { + interimSpace = InterimSpacePresetToValue(preset: interimSpacePreset) + } + } + + /// The space between views. + open var interimSpace: InterimSpace = 0 { + didSet { + reload() + } + } + + /// An Array of UIViews. + open var views = [UIView]() { + didSet { + reload() + } + } + + /// An Optional base view size. + open var baseSize = CGSize(width: 48, height: 48) { + didSet { + reload() + } + } + + /// Size of views. + open var itemSize = CGSize(width: 48, height: 48) { + didSet { + reload() + } + } + + /// Reload the view layout. + open func reload() { + isOpened = false + + for i in 0.. Void)? = nil, completion: ((UIView) -> Void)? = nil) { + guard isEnabled else { + return + } + + disable() + + switch springDirection { + case .up: + expandUp(duration: duration, delay: delay, usingSpringWithDamping: usingSpringWithDamping, initialSpringVelocity: initialSpringVelocity, options: options, animations: animations, completion: completion) + case .down: + expandDown(duration: duration, delay: delay, usingSpringWithDamping: usingSpringWithDamping, initialSpringVelocity: initialSpringVelocity, options: options, animations: animations, completion: completion) + case .left: + expandLeft(duration: duration, delay: delay, usingSpringWithDamping: usingSpringWithDamping, initialSpringVelocity: initialSpringVelocity, options: options, animations: animations, completion: completion) + case .right: + expandRight(duration: duration, delay: delay, usingSpringWithDamping: usingSpringWithDamping, initialSpringVelocity: initialSpringVelocity, options: options, animations: animations, completion: completion) + } + } + + /** + Contracts the Spring component with animation options. + - Parameter duration: The time for each view's animation. + - Parameter delay: A delay time for each view's animation. + - Parameter usingSpringWithDamping: A damping ratio for the animation. + - Parameter initialSpringVelocity: The initial velocity for the animation. + - Parameter options: Options to pass to the animation. + - Parameter animations: An animation block to execute on each view's animation. + - Parameter completion: A completion block to execute on each view's animation. + */ + open func contract(duration: TimeInterval = 0.15, delay: TimeInterval = 0, usingSpringWithDamping: CGFloat = 0.5, initialSpringVelocity: CGFloat = 0, options: UIViewAnimationOptions = [], animations: ((UIView) -> Void)? = nil, completion: ((UIView) -> Void)? = nil) { + guard isEnabled else { + return + } + + disable() + + switch springDirection { + case .up: + contractUp(duration: duration, delay: delay, usingSpringWithDamping: usingSpringWithDamping, initialSpringVelocity: initialSpringVelocity, options: options, animations: animations, completion: completion) + case .down: + contractDown(duration: duration, delay: delay, usingSpringWithDamping: usingSpringWithDamping, initialSpringVelocity: initialSpringVelocity, options: options, animations: animations, completion: completion) + case .left: + contractLeft(duration: duration, delay: delay, usingSpringWithDamping: usingSpringWithDamping, initialSpringVelocity: initialSpringVelocity, options: options, animations: animations, completion: completion) + case .right: + contractRight(duration: duration, delay: delay, usingSpringWithDamping: usingSpringWithDamping, initialSpringVelocity: initialSpringVelocity, options: options, animations: animations, completion: completion) + } + } +} + +extension SpringAnimation { + /** + Handles the animation open completion. + - Parameter view: A UIView. + - Parameter completion: A completion handler. + */ + fileprivate func handleOpenCompletion(view: UIView, completion: ((UIView) -> Void)?) { + enable(view: view) + + if view == views.last { + isOpened = true + } + + completion?(view) + } + + /** + Handles the animation contract completion. + - Parameter view: A UIView. + - Parameter completion: A completion handler. + */ + fileprivate func handleCloseCompletion(view: UIView, completion: ((UIView) -> Void)?) { + view.isHidden = true + enable(view: view) + + if view == views.last { + isOpened = false + } + + completion?(view) + } +} + +extension SpringAnimation { + /** + Open the Menu component with animation options in the Up direction. + - Parameter duration: The time for each view's animation. + - Parameter delay: A delay time for each view's animation. + - Parameter usingSpringWithDamping: A damping ratio for the animation. + - Parameter initialSpringVelocity: The initial velocity for the animation. + - Parameter options: Options to pass to the animation. + - Parameter animations: An animation block to execute on each view's animation. + - Parameter completion: A completion block to execute on each view's animation. + */ + fileprivate func expandUp(duration: TimeInterval, delay: TimeInterval, usingSpringWithDamping: CGFloat, initialSpringVelocity: CGFloat, options: UIViewAnimationOptions, animations: ((UIView) -> Void)?, completion: ((UIView) -> Void)?) { + for i in 0.. Void)?, completion: ((UIView) -> Void)?) { + for i in 0.. Void)?, completion: ((UIView) -> Void)?) { + + for i in 0.. Void)?, completion: ((UIView) -> Void)?) { + guard let first = views.first else { + return + } + + for i in 0.. Void)?, completion: ((UIView) -> Void)?) { + + for i in 0.. Void)?, completion: ((UIView) -> Void)?) { + guard let first = views.first else { + return + } + + for i in 0.. Void)?, completion: ((UIView) -> Void)?) { + + for i in 0.. Void)?, completion: ((UIView) -> Void)?) { + guard let first = views.first else { + return + } + + let w = baseSize.width + + for i in 0... + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -37,18 +37,22 @@ extension UIViewController { through child UIViewControllers. */ public var statusBarController: StatusBarController? { - var viewController: UIViewController? = self - while nil != viewController { - if viewController is StatusBarController { - return viewController as? StatusBarController - } - viewController = viewController?.parent - } - return nil + return traverseViewControllerHierarchyForClassType() } } -open class StatusBarController: RootController { +open class StatusBarController: TransitionController { + /** + A Display value to indicate whether or not to + display the rootViewController to the full view + bounds, or up to the toolbar height. + */ + open var displayStyle = DisplayStyle.full { + didSet { + layoutSubviews() + } + } + /// Device status bar style. open var statusBarStyle: UIStatusBarStyle { get { @@ -70,44 +74,53 @@ open class StatusBarController: RootController { } } + /// An adjustment based on the rules for displaying the statusBar. + open var statusBarOffsetAdjustment: CGFloat { + return Application.shouldStatusBarBeHidden || statusBar.isHidden ? 0 : statusBar.height + } + /// A boolean that indicates to hide the statusBar on rotation. - open var shouldHideStatusBarOnRotation = true + open var shouldHideStatusBarOnRotation = false /// A reference to the statusBar. open let statusBar = UIView() - /** - To execute in the order of the layout chain, override this - method. LayoutSubviews should be called immediately, unless you - have a certain need. - */ open override func layoutSubviews() { super.layoutSubviews() + if shouldHideStatusBarOnRotation { statusBar.isHidden = Application.shouldStatusBarBeHidden } statusBar.width = view.width - rootViewController.view.frame = view.bounds - } + + switch displayStyle { + case .partial: + let h = statusBar.height + container.y = h + container.height = view.height - h + case .full: + container.frame = view.bounds + } + + rootViewController.view.frame = container.bounds + + container.zPosition = statusBar.zPosition + (Application.shouldStatusBarBeHidden ? 1 : -1) + } - /** - Prepares the view instance when intialized. When subclassing, - it is recommended to override the prepare method - to initialize property values and other setup operations. - The super.prepare method should always be called immediately - when subclassing. - */ open override func prepare() { super.prepare() prepareStatusBar() } } -extension StatusBarController { +fileprivate extension StatusBarController { /// Prepares the statusBar. - fileprivate func prepareStatusBar() { - statusBar.backgroundColor = .white + func prepareStatusBar() { + if nil == statusBar.backgroundColor { + statusBar.backgroundColor = .white + } + statusBar.height = 20 view.addSubview(statusBar) } diff --git a/Example/Pods/Material/Sources/iOS/Switch.swift b/Example/Pods/Material/Sources/iOS/Switch.swift index fec4524..d9a6ab9 100644 --- a/Example/Pods/Material/Sources/iOS/Switch.swift +++ b/Example/Pods/Material/Sources/iOS/Switch.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -166,7 +166,7 @@ open class Switch: UIControl { } /// Button view reference. - open fileprivate(set) var button: FabButton { + open fileprivate(set) var button: FABButton { didSet { prepareButton() } @@ -208,15 +208,15 @@ open class Switch: UIControl { buttonOnColor = Color.blue.darken2 trackOnColor = Color.blue.lighten3 buttonOffColor = Color.blueGrey.lighten4 - trackOffColor = Color.grey.lighten3 + trackOffColor = Color.grey.lighten2 buttonOnDisabledColor = Color.grey.lighten2 - trackOnDisabledColor = Color.grey.lighten3 + trackOnDisabledColor = Color.grey.lighten2 buttonOffDisabledColor = Color.grey.lighten2 - trackOffDisabledColor = Color.grey.lighten3 + trackOffDisabledColor = Color.grey.lighten2 case .dark: buttonOnColor = Color.blue.lighten1 trackOnColor = Color.blue.lighten2.withAlphaComponent(0.5) - buttonOffColor = Color.grey.lighten3 + buttonOffColor = Color.grey.lighten2 trackOffColor = Color.blueGrey.lighten4.withAlphaComponent(0.5) buttonOnDisabledColor = Color.grey.darken3 trackOnDisabledColor = Color.grey.lighten1.withAlphaComponent(0.2) @@ -262,7 +262,7 @@ open class Switch: UIControl { */ public required init?(coder aDecoder: NSCoder) { track = UIView() - button = FabButton() + button = FABButton() super.init(coder: aDecoder) prepare() } @@ -276,7 +276,7 @@ open class Switch: UIControl { */ public override init(frame: CGRect) { track = UIView() - button = FabButton() + button = FABButton() super.init(frame: frame) prepare() } @@ -289,7 +289,7 @@ open class Switch: UIControl { */ public init(state: SwitchState = .off, style: SwitchStyle = .dark, size: SwitchSize = .medium) { track = UIView() - button = FabButton() + button = FABButton() super.init(frame: .zero) prepare() prepareSwitchState(state: state) @@ -388,7 +388,7 @@ extension Switch { internalSwitchState = state if animated { - animateToState(state: state) { [weak self] _ in + animateToState(state: state) { [weak self, isTriggeredByUserInteraction = isTriggeredByUserInteraction] _ in guard isTriggeredByUserInteraction else { return } @@ -467,23 +467,23 @@ extension Switch { fileprivate func animateToState(state: SwitchState, completion: ((Switch) -> Void)? = nil) { isUserInteractionEnabled = false UIView.animate(withDuration: 0.15, - delay: 0.05, - options: [.curveEaseIn, .curveEaseOut], - animations: { [weak self] in - guard let s = self else { - return - } - - s.button.x = .on == state ? s.onPosition + s.bounceOffset : s.offPosition - s.bounceOffset - s.styleForState(state: state) + delay: 0.05, + options: [.curveEaseIn, .curveEaseOut], + animations: { [weak self] in + guard let s = self else { + return + } + + s.button.x = .on == state ? s.onPosition + s.bounceOffset : s.offPosition - s.bounceOffset + s.styleForState(state: state) }) { [weak self] _ in UIView.animate(withDuration: 0.15, - animations: { [weak self] in - guard let s = self else { - return - } - - s.button.x = .on == state ? s.onPosition : s.offPosition + animations: { [weak self] in + guard let s = self else { + return + } + + s.button.x = .on == state ? s.onPosition : s.offPosition }) { [weak self] _ in guard let s = self else { return @@ -498,12 +498,12 @@ extension Switch { extension Switch { /** - Handle the TouchUpOutside and TouchCancel events. + Handle the TouchUpOutside and TouchCancel moments. - Parameter sender: A UIButton. - Parameter event: A UIEvent. */ @objc - fileprivate func handleTouchUpOutsideOrCanceled(sender: FabButton, event: UIEvent) { + fileprivate func handleTouchUpOutsideOrCanceled(sender: FABButton, event: UIEvent) { guard let v = event.touches(for: sender)?.first else { return } @@ -524,7 +524,7 @@ extension Switch { - Parameter event: A UIEvent. */ @objc - fileprivate func handleTouchDragInside(sender: FabButton, event: UIEvent) { + fileprivate func handleTouchDragInside(sender: FABButton, event: UIEvent) { guard let v = event.touches(for: sender)?.first else { return } diff --git a/Example/Pods/Material/Sources/iOS/TabBar.swift b/Example/Pods/Material/Sources/iOS/TabBar.swift index 6a1935a..6b56db3 100644 --- a/Example/Pods/Material/Sources/iOS/TabBar.swift +++ b/Example/Pods/Material/Sources/iOS/TabBar.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,6 +30,13 @@ import UIKit +open class TabItem: FlatButton { + open override func prepare() { + super.prepare() + pulseAnimation = .none + } +} + @objc(TabBarLineAlignment) public enum TabBarLineAlignment: Int { case top @@ -39,36 +46,90 @@ public enum TabBarLineAlignment: Int { @objc(TabBarDelegate) public protocol TabBarDelegate { /** - A delegation method that is executed when the button will trigger the + A delegation method that is executed to determine if the TabBar should + transition to the next tab. + - Parameter tabBar: A TabBar. + - Parameter tabItem: A TabItem. + - Returns: A Boolean. + */ + @objc + optional func tabBar(tabBar: TabBar, shouldSelect tabItem: TabItem) -> Bool + + /** + A delegation method that is executed when the tabItem will trigger the animation to the next tab. - Parameter tabBar: A TabBar. - - Parameter button: A UIButton. + - Parameter tabItem: A TabItem. */ @objc - optional func tabBar(tabBar: TabBar, willSelect button: UIButton) + optional func tabBar(tabBar: TabBar, willSelect tabItem: TabItem) /** - A delegation method that is executed when the button did complete the + A delegation method that is executed when the tabItem did complete the animation to the next tab. - Parameter tabBar: A TabBar. - - Parameter button: A UIButton. + - Parameter tabItem: A TabItem. */ @objc - optional func tabBar(tabBar: TabBar, didSelect button: UIButton) + optional func tabBar(tabBar: TabBar, didSelect tabItem: TabItem) +} + +@objc(TabBarStyle) +public enum TabBarStyle: Int { + case auto + case nonScrollable + case scrollable } open class TabBar: Bar { - /// A boolean indicating if the TabBar line is in an animation state. - open internal(set) var isAnimating = false + /// Only for inital load to get the line animation correct. + fileprivate var shouldNotAnimateLineView = false + + /// The total width of the tabItems. + fileprivate var tabItemsTotalWidth: CGFloat { + var w: CGFloat = 0 + let q = 2 * tabItemsInterimSpace + let p = q + tabItemsInterimSpace + + for v in tabItems { + let x = v.sizeThatFits(CGSize(width: .greatestFiniteMagnitude, height: scrollView.height)).width + w += x + w += p + } + + w -= tabItemsInterimSpace + + return w + } + + /// An enum that determines the tab bar style. + open var tabBarStyle = TabBarStyle.auto { + didSet { + layoutSubviews() + } + } + + /// A reference to the scroll view when the tab bar style is scrollable. + open let scrollView = UIScrollView() + + /// Enables and disables bouncing when swiping. + open var isScrollBounceEnabled: Bool { + get { + return scrollView.bounces + } + set(value) { + scrollView.bounces = value + } + } /// A delegation reference. open weak var delegate: TabBarDelegate? - /// The currently selected button. - open internal(set) var selected: UIButton? + /// The currently selected tabItem. + open internal(set) var selectedTabItem: TabItem? - /// A preset wrapper around contentEdgeInsets. - open override var contentEdgeInsetsPreset: EdgeInsetsPreset { + /// A preset wrapper around tabItems contentEdgeInsets. + open var tabItemsContentEdgeInsetsPreset: EdgeInsetsPreset { get { return contentView.grid.contentEdgeInsetsPreset } @@ -79,7 +140,7 @@ open class TabBar: Bar { /// A reference to EdgeInsets. @IBInspectable - open override var contentEdgeInsets: EdgeInsets { + open var tabItemsContentEdgeInsets: EdgeInsets { get { return contentView.grid.contentEdgeInsets } @@ -88,8 +149,8 @@ open class TabBar: Bar { } } - /// A preset wrapper around interimSpace. - open override var interimSpacePreset: InterimSpacePreset { + /// A preset wrapper around tabItems interimSpace. + open var tabItemsInterimSpacePreset: InterimSpacePreset { get { return contentView.grid.interimSpacePreset } @@ -98,9 +159,9 @@ open class TabBar: Bar { } } - /// A wrapper around contentView.grid.interimSpace. + /// A wrapper around tabItems interimSpace. @IBInspectable - open override var interimSpace: InterimSpace { + open var tabItemsInterimSpace: InterimSpace { get { return contentView.grid.interimSpace } @@ -109,33 +170,18 @@ open class TabBar: Bar { } } - /// Buttons. - open var buttons = [UIButton]() { + /// TabItems. + open var tabItems = [TabItem]() { didSet { for b in oldValue { b.removeFromSuperview() } - centerViews = buttons as [UIView] - + prepareTabItems() layoutSubviews() } } - /// A boolean to animate the line when touched. - @IBInspectable - open var isLineAnimated = true { - didSet { - for b in buttons { - if isLineAnimated { - prepareLineAnimationHandler(button: b) - } else { - removeLineAnimationHandler(button: b) - } - } - } - } - /// A reference to the line UIView. open let line = UIView() @@ -167,146 +213,230 @@ open class TabBar: Bar { } open override func layoutSubviews() { - super.layoutSubviews() + super.layoutSubviews() guard willLayout else { return } - guard 0 < buttons.count else { - return - } - - for b in buttons { - b.grid.columns = 0 - b.cornerRadius = 0 - b.contentEdgeInsets = .zero - - if isLineAnimated { - prepareLineAnimationHandler(button: b) - } - } - contentView.grid.axis.columns = buttons.count - contentView.grid.reload() - - if nil == selected { - selected = buttons.first - } - - line.frame = CGRect(x: selected!.x, y: .bottom == lineAlignment ? height - lineHeight : 0, width: selected!.width, height: lineHeight) + layoutScrollView() + layoutLine() + + updateScrollView() } - - /** - Prepares the view instance when intialized. When subclassing, - it is recommended to override the prepare method - to initialize property values and other setup operations. - The super.prepare method should always be called immediately - when subclassing. - */ + open override func prepare() { super.prepare() contentEdgeInsetsPreset = .none - interimSpacePreset = .none - prepareLine() + interimSpacePreset = .interimSpace6 + tabItemsInterimSpacePreset = .interimSpace4 + + prepareContentView() + prepareScrollView() prepareDivider() + prepareLine() } } -extension TabBar { +fileprivate extension TabBar { // Prepares the line. - fileprivate func prepareLine() { - line.zPosition = 6000 + func prepareLine() { + line.zPosition = 10000 lineColor = Color.blue.base lineHeight = 3 - addSubview(line) + scrollView.addSubview(line) } /// Prepares the divider. - fileprivate func prepareDivider() { + func prepareDivider() { + dividerColor = Color.grey.lighten2 dividerAlignment = .top } + /// Prepares the tabItems. + func prepareTabItems() { + shouldNotAnimateLineView = true + + for v in tabItems { + v.grid.columns = 0 + v.contentEdgeInsets = .zero + + prepareLineAnimationHandler(tabItem: v) + } + + selectedTabItem = tabItems.first + } + /** Prepares the line animation handlers. - - Parameter button: A UIButton. + - Parameter tabItem: A TabItem. */ - fileprivate func prepareLineAnimationHandler(button: UIButton) { - removeLineAnimationHandler(button: button) - button.addTarget(self, action: #selector(handleButton(button:)), for: .touchUpInside) + func prepareLineAnimationHandler(tabItem: TabItem) { + removeLineAnimationHandler(tabItem: tabItem) + tabItem.addTarget(self, action: #selector(handleLineAnimation(tabItem:)), for: .touchUpInside) + } + + /// Prepares the contentView. + func prepareContentView() { + contentView.zPosition = 6000 + } + + /// Prepares the scroll view. + func prepareScrollView() { + scrollView.showsVerticalScrollIndicator = false + scrollView.showsHorizontalScrollIndicator = false + centerViews = [scrollView] + } +} + +fileprivate extension TabBar { + /// Layout the scrollView. + func layoutScrollView() { + contentView.grid.reload() + + if .scrollable == tabBarStyle || (.auto == tabBarStyle && tabItemsTotalWidth > scrollView.width) { + var w: CGFloat = 0 + let q = 2 * tabItemsInterimSpace + let p = q + tabItemsInterimSpace + + for v in tabItems { + let x = v.sizeThatFits(CGSize(width: .greatestFiniteMagnitude, height: scrollView.height)).width + v.height = scrollView.height + v.width = x + q + v.x = w + w += x + w += p + + if scrollView != v.superview { + v.removeFromSuperview() + scrollView.addSubview(v) + } + } + + w -= tabItemsInterimSpace + + scrollView.contentSize = CGSize(width: w, height: scrollView.height) + + } else { + scrollView.grid.begin() + scrollView.grid.views = tabItems + scrollView.grid.axis.columns = tabItems.count + scrollView.grid.contentEdgeInsets = tabItemsContentEdgeInsets + scrollView.grid.interimSpace = tabItemsInterimSpace + scrollView.grid.commit() + scrollView.contentSize = scrollView.frame.size + } } + /// Layout the line view. + func layoutLine() { + guard let v = selectedTabItem else { + return + } + + guard shouldNotAnimateLineView else { + line.animate(.duration(0), + .size(CGSize(width: v.width, height: lineHeight)), + .position(CGPoint(x: v.center.x, y: .bottom == lineAlignment ? height - lineHeight / 2 : lineHeight / 2))) + return + } + + line.frame = CGRect(x: v.x, y: .bottom == lineAlignment ? scrollView.height - lineHeight : 0, width: v.width, height: lineHeight) + + shouldNotAnimateLineView = false + } +} + +fileprivate extension TabBar { /** Removes the line animation handlers. - - Parameter button: A UIButton. + - Parameter tabItem: A TabItem. */ - fileprivate func removeLineAnimationHandler(button: UIButton) { - button.removeTarget(self, action: #selector(handleButton(button:)), for: .touchUpInside) + func removeLineAnimationHandler(tabItem: TabItem) { + tabItem.removeTarget(self, action: #selector(handleLineAnimation(tabItem:)), for: .touchUpInside) } } -extension TabBar { - /// Handles the button touch event. +fileprivate extension TabBar { + /// Handles the tabItem touch event. @objc - internal func handleButton(button: UIButton) { - animate(to: button, isTriggeredByUserInteraction: true) + func handleLineAnimation(tabItem: TabItem) { + guard !(false == delegate?.tabBar?(tabBar: self, shouldSelect: tabItem)) else { + return + } + + animate(to: tabItem, isTriggeredByUserInteraction: true) } } extension TabBar { /** - Selects a given index from the buttons array. + Selects a given index from the tabItems array. - Parameter at index: An Int. - Paramater completion: An optional completion block. */ - open func select(at index: Int, completion: ((UIButton) -> Void)? = nil) { - guard -1 < index, index < buttons.count else { + open func select(at index: Int, completion: ((TabItem) -> Void)? = nil) { + guard -1 < index, index < tabItems.count else { return } - animate(to: buttons[index], isTriggeredByUserInteraction: false, completion: completion) + + animate(to: tabItems[index], isTriggeredByUserInteraction: false, completion: completion) } /** - Animates to a given button. - - Parameter to button: A UIButton. + Animates to a given tabItem. + - Parameter to tabItem: A TabItem. - Parameter completion: An optional completion block. */ - open func animate(to button: UIButton, completion: ((UIButton) -> Void)? = nil) { - animate(to: button, isTriggeredByUserInteraction: false, completion: completion) + open func animate(to tabItem: TabItem, completion: ((TabItem) -> Void)? = nil) { + animate(to: tabItem, isTriggeredByUserInteraction: false, completion: completion) } - +} + +fileprivate extension TabBar { /** - Animates to a given button. - - Parameter to button: A UIButton. + Animates to a given tabItem. + - Parameter to tabItem: A TabItem. - Parameter isTriggeredByUserInteraction: A boolean indicating whether the state was changed by a user interaction, true if yes, false otherwise. - Parameter completion: An optional completion block. */ - fileprivate func animate(to button: UIButton, isTriggeredByUserInteraction: Bool, completion: ((UIButton) -> Void)? = nil) { + func animate(to tabItem: TabItem, isTriggeredByUserInteraction: Bool, completion: ((TabItem) -> Void)? = nil) { if isTriggeredByUserInteraction { - delegate?.tabBar?(tabBar: self, willSelect: button) + delegate?.tabBar?(tabBar: self, willSelect: tabItem) } - selected = button - isAnimating = true + selectedTabItem = tabItem - UIView.animate(withDuration: 0.25, animations: { [weak self, button = button] in - guard let s = self else { - return - } - - s.line.center.x = button.center.x - s.line.width = button.width - }) { [weak self, button = button, completion = completion] _ in - guard let s = self else { - return - } - - s.isAnimating = false - - if isTriggeredByUserInteraction { - s.delegate?.tabBar?(tabBar: s, didSelect: button) - } - - completion?(button) + line.animate(.duration(0.25), + .size(CGSize(width: tabItem.width, height: lineHeight)), + .position(CGPoint(x: tabItem.center.x, y: .bottom == lineAlignment ? height - lineHeight / 2 : lineHeight / 2)), + .completion { [weak self, isTriggeredByUserInteraction = isTriggeredByUserInteraction, tabItem = tabItem, completion = completion] _ in + guard let s = self else { + return + } + + if isTriggeredByUserInteraction { + s.delegate?.tabBar?(tabBar: s, didSelect: tabItem) + } + + completion?(tabItem) + }) + + updateScrollView() + } +} + +fileprivate extension TabBar { + /// Updates the scrollView. + func updateScrollView() { + guard let v = selectedTabItem else { + return + } + + if !scrollView.bounds.contains(v.frame) { + let contentOffsetX = (v.x < scrollView.bounds.minX) ? v.x : v.frame.maxX - scrollView.bounds.width + let normalizedOffsetX = min(max(contentOffsetX, 0), scrollView.contentSize.width - scrollView.bounds.width) + scrollView.setContentOffset(CGPoint(x: normalizedOffsetX, y: 0), animated: true) } } } diff --git a/Example/Pods/Material/Sources/iOS/TableView.swift b/Example/Pods/Material/Sources/iOS/TableView.swift index 0e8e4cb..a6e0e73 100644 --- a/Example/Pods/Material/Sources/iOS/TableView.swift +++ b/Example/Pods/Material/Sources/iOS/TableView.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,4 +30,45 @@ import UIKit -open class TableView: UITableView {} +open class TableView: UITableView { + /** + An initializer that initializes the object with a NSCoder object. + - Parameter aDecoder: A NSCoder instance. + */ + public required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + prepare() + } + + public override init(frame: CGRect, style: UITableViewStyle) { + super.init(frame: frame, style: style) + prepare() + } + + /** + An initializer that initializes the object. + - Parameter frame: A CGRect defining the view's frame. + */ + public convenience init(frame: CGRect) { + self.init(frame: frame, style: .plain) + } + + /// A convenience initializer that initializes the object. + public convenience init() { + self.init(frame: .zero) + } + + /** + Prepares the view instance when intialized. When subclassing, + it is recommended to override the prepare method + to initialize property values and other setup operations. + The super.prepare method should always be called immediately + when subclassing. + */ + open func prepare() { + backgroundColor = .white + contentScaleFactor = Screen.scale + separatorStyle = .none + register(TableViewCell.self, forCellReuseIdentifier: "TableViewCell") + } +} diff --git a/Example/Pods/Material/Sources/iOS/TableViewCell.swift b/Example/Pods/Material/Sources/iOS/TableViewCell.swift index d3d60cf..771e20d 100644 --- a/Example/Pods/Material/Sources/iOS/TableViewCell.swift +++ b/Example/Pods/Material/Sources/iOS/TableViewCell.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,7 +30,7 @@ import UIKit -open class TableViewCell: UITableViewCell, Pulseable { +open class TableViewCell: UITableViewCell, Pulseable, PulseableLayer { /** A CAShapeLayer used to manage elements that would be affected by the clipToBounds property of the backing layer. For example, this @@ -40,7 +40,12 @@ open class TableViewCell: UITableViewCell, Pulseable { open let visualLayer = CAShapeLayer() /// A Pulse reference. - fileprivate var pulse: Pulse! + internal var pulse: Pulse! + + /// A reference to the pulse layer. + internal var pulseLayer: CALayer? { + return pulse.pulseLayer + } /// PulseAnimation value. open var pulseAnimation: PulseAnimation { @@ -97,7 +102,7 @@ open class TableViewCell: UITableViewCell, Pulseable { - Parameter reuseIdentifier: A String identifier. */ public override init(style: UITableViewCellStyle, reuseIdentifier: String!) { - super.init(style: style, reuseIdentifier: reuseIdentifier) + super.init(style: .subtitle, reuseIdentifier: reuseIdentifier) prepare() } @@ -106,6 +111,7 @@ open class TableViewCell: UITableViewCell, Pulseable { layoutShape() layoutVisualLayer() layoutShadowPath() + layoutDivider() } /** @@ -114,11 +120,9 @@ open class TableViewCell: UITableViewCell, Pulseable { from the center. */ open func pulse(point: CGPoint? = nil) { - let p = point ?? center - - pulse.expandAnimation(point: p) - Motion.delay(time: 0.35) { [weak self] in - self?.pulse.contractAnimation() + pulse.expand(point: point ?? center) + Motion.delay(0.35) { [weak self] in + self?.pulse.contract() } } @@ -130,7 +134,7 @@ open class TableViewCell: UITableViewCell, Pulseable { */ open override func touchesBegan(_ touches: Set, with event: UIEvent?) { super.touchesBegan(touches, with: event) - pulse.expandAnimation(point: layer.convert(touches.first!.location(in: self), from: layer)) + pulse.expand(point: layer.convert(touches.first!.location(in: self), from: layer)) } /** @@ -141,7 +145,7 @@ open class TableViewCell: UITableViewCell, Pulseable { */ open override func touchesEnded(_ touches: Set, with event: UIEvent?) { super.touchesEnded(touches, with: event) - pulse.contractAnimation() + pulse.contract() } /** @@ -152,7 +156,7 @@ open class TableViewCell: UITableViewCell, Pulseable { */ open override func touchesCancelled(_ touches: Set, with event: UIEvent?) { super.touchesCancelled(touches, with: event) - pulse.contractAnimation() + pulse.contract() } /** @@ -165,7 +169,7 @@ open class TableViewCell: UITableViewCell, Pulseable { open func prepare() { selectionStyle = .none separatorInset = .zero - contentScaleFactor = Screen.scale + contentScaleFactor = Screen.scale imageView?.isUserInteractionEnabled = false textLabel?.isUserInteractionEnabled = false detailTextLabel?.isUserInteractionEnabled = false diff --git a/Example/Pods/Material/Sources/iOS/TableViewController.swift b/Example/Pods/Material/Sources/iOS/TableViewController.swift index fa61b4f..97b9422 100644 --- a/Example/Pods/Material/Sources/iOS/TableViewController.swift +++ b/Example/Pods/Material/Sources/iOS/TableViewController.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/Example/Pods/Material/Sources/iOS/TabsController.swift b/Example/Pods/Material/Sources/iOS/TabsController.swift new file mode 100644 index 0000000..22977b7 --- /dev/null +++ b/Example/Pods/Material/Sources/iOS/TabsController.swift @@ -0,0 +1,408 @@ +/* + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, 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 of CosmicMind 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. + */ + +import UIKit + +fileprivate var TabItemKey: UInt8 = 0 + +@objc(TabBarAlignment) +public enum TabBarAlignment: Int { + case top + case bottom +} + +extension UIViewController { + /// tabItem reference. + public private(set) var tabItem: TabItem { + get { + return AssociatedObject.get(base: self, key: &TabItemKey) { + return TabItem() + } + } + set(value) { + AssociatedObject.set(base: self, key: &TabItemKey, value: value) + } + } +} + +extension UIViewController { + /** + A convenience property that provides access to the TabsController. + This is the recommended method of accessing the TabsController + through child UIViewControllers. + */ + public var tabsController: TabsController? { + return traverseViewControllerHierarchyForClassType() + } +} + +@objc(TabsControllerDelegate) +public protocol TabsControllerDelegate { + /** + A delegation method that is executed to determine if the TabsController should + transition to the next view controller. + - Parameter tabBar: A TabsController. + - Parameter tabItem: A TabItem. + - Returns: A Boolean. + */ + @objc + optional func tabsController(tabsController: TabsController, shouldSelect viewController: UIViewController) -> Bool + + /** + A delegation method that is executed when the view controller will transitioned to. + - Parameter tabsController: A TabsController. + - Parameter viewController: A UIViewController. + */ + @objc + optional func tabsController(tabsController: TabsController, willSelect viewController: UIViewController) + + /** + A delegation method that is executed when the view controller has been transitioned to. + - Parameter tabsController: A TabsController. + - Parameter viewController: A UIViewController. + */ + @objc + optional func tabsController(tabsController: TabsController, didSelect viewController: UIViewController) +} + +open class TabsController: TransitionController { + /** + A Display value to indicate whether or not to + display the rootViewController to the full view + bounds, or up to the toolbar height. + */ + open var displayStyle = DisplayStyle.partial { + didSet { + layoutSubviews() + } + } + + /// The TabBar used to switch between view controllers. + @IBInspectable + open let tabBar = TabBar() + + /// A delegation reference. + open weak var delegate: TabsControllerDelegate? + + /// An Array of UIViewControllers. + open var viewControllers: [UIViewController] { + didSet { + selectedIndex = 0 + + prepareRootViewController() + prepareTabBar() + layoutSubviews() + } + } + + /// A reference to the currently selected view controller index value. + @IBInspectable + open fileprivate(set) var selectedIndex = 0 + + /// The tabBar alignment. + open var tabBarAlignment = TabBarAlignment.bottom { + didSet { + layoutSubviews() + } + } + + /** + An initializer that initializes the object with a NSCoder object. + - Parameter aDecoder: A NSCoder instance. + */ + public required init?(coder aDecoder: NSCoder) { + viewControllers = [] + super.init(coder: aDecoder) + } + + /** + An initializer that accepts an Array of UIViewControllers. + - Parameter viewControllers: An Array of UIViewControllers. + */ + public init(viewControllers: [UIViewController], selectedIndex: Int = 0) { + self.viewControllers = viewControllers + self.selectedIndex = selectedIndex + super.init(nibName: nil, bundle: nil) + } + + fileprivate override init(rootViewController: UIViewController) { + self.viewControllers = [] + super.init(rootViewController: rootViewController) + } + + open override func viewDidLoad() { + super.viewDidLoad() + prepare() + } + + open override func viewWillLayoutSubviews() { + super.viewWillLayoutSubviews() + layoutSubviews() + } + + open override func layoutSubviews() { + super.layoutSubviews() + layoutTabBar() + layoutContainer() + layoutRootViewController() + } + + open override func prepare() { + super.prepare() + view.backgroundColor = .white + view.contentScaleFactor = Screen.scale + + prepareViewControllers() + prepareTabBar() + prepareTabItems() + } + + open override func transition(to viewController: UIViewController, completion: ((Bool) -> Void)?) { + transition(to: viewController, isTriggeredByUserInteraction: false, completion: completion) + } +} + +fileprivate extension TabsController { + /** + Transitions to the given view controller. + - Parameter to viewController: A UIViewController. + - Parameter isTriggeredByUserInteraction: A Boolean. + - Parameter completion: An optional completion block. + */ + func transition(to viewController: UIViewController, isTriggeredByUserInteraction: Bool, completion: ((Bool) -> Void)?) { + guard let fvc = rootViewController else { + return + } + + let tvc = viewController + tvc.view.isHidden = false + tvc.view.frame = container.bounds + + let fvcIndex = viewControllers.index(of: fvc) + let tvcIndex = viewControllers.index(of: viewController) + + var isAuto = false + + switch tvc.motionModalTransitionType { + case .auto: + isAuto = true + tvc.motionModalTransitionType = fvcIndex! < tvcIndex! ? .slide(direction: .left) : .slide(direction: .right) + default:break + } + + if isTriggeredByUserInteraction { + delegate?.tabsController?(tabsController: self, willSelect: tvc) + } + + view.isUserInteractionEnabled = false + Motion.shared.transition(from: fvc, to: tvc, in: container) { [weak self, tvc = tvc, isAuto = isAuto, completion = completion] (isFinished) in + guard let s = self else { + return + } + + if isAuto { + tvc.motionModalTransitionType = .auto + } + + s.rootViewController = tvc + s.view.isUserInteractionEnabled = true + + completion?(isFinished) + + if isTriggeredByUserInteraction { + s.delegate?.tabsController?(tabsController: s, didSelect: tvc) + } + } + } +} + +internal extension TabsController { + override func prepareRootViewController() { + rootViewController = viewControllers[selectedIndex] + } +} + + +fileprivate extension TabsController { + /// Prepares all the view controllers. + func prepareViewControllers() { + for i in 0... + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -40,27 +40,27 @@ public enum TextFieldPlaceholderAnimation: Int { public protocol TextFieldDelegate: UITextFieldDelegate { /** A delegation method that is executed when the textField changed. - - Parameter textField: A UITextField. + - Parameter textField: A TextField. - Parameter didChange text: An optional String. */ @objc - optional func textField(textField: UITextField, didChange text: String?) + optional func textField(textField: TextField, didChange text: String?) /** A delegation method that is executed when the textField will clear. - - Parameter textField: A UITextField. + - Parameter textField: A TextField. - Parameter willClear text: An optional String. */ @objc - optional func textField(textField: UITextField, willClear text: String?) + optional func textField(textField: TextField, willClear text: String?) /** A delegation method that is executed when the textField is cleared. - - Parameter textField: A UITextField. + - Parameter textField: A TextField. - Parameter didClear text: An optional String. */ @objc - optional func textField(textField: UITextField, didClear text: String?) + optional func textField(textField: TextField, didClear text: String?) } open class TextField: UITextField { @@ -76,7 +76,12 @@ open class TextField: UITextField { /// Set the placeholder animation value. open var placeholderAnimation = TextFieldPlaceholderAnimation.default { didSet { - placeholderLabel.isHidden = .hidden == placeholderAnimation && !isEmpty + guard isEditing else { + placeholderLabel.isHidden = !isEmpty && .hidden == placeholderAnimation + return + } + + placeholderLabel.isHidden = .hidden == placeholderAnimation } } @@ -85,6 +90,12 @@ open class TextField: UITextField { return 0 == text?.utf16.count } + open override var text: String? { + didSet { + placeholderAnimation = { placeholderAnimation }() + } + } + open override var leftView: UIView? { didSet { prepareLeftView() @@ -101,7 +112,7 @@ open class TextField: UITextField { return leftViewOffset + height } - /// The leftView width value. + /// The leftView offset value. open var leftViewOffset: CGFloat = 16 /// Placeholder normal text @@ -133,8 +144,8 @@ open class TextField: UITextField { } - /// Divider active height. - @IBInspectable + /// Divider active height. + @IBInspectable open var dividerActiveHeight: CGFloat = 2 { didSet { guard isEditing else { @@ -144,10 +155,10 @@ open class TextField: UITextField { dividerThickness = dividerActiveHeight } } - - /// Divider normal color. - @IBInspectable - open var dividerNormalColor = Color.darkText.dividers { + + /// Divider normal color. + @IBInspectable + open var dividerNormalColor = Color.grey.lighten2 { didSet { guard !isEditing else { return @@ -156,63 +167,79 @@ open class TextField: UITextField { dividerColor = dividerNormalColor } } - - /// Divider active color. - @IBInspectable + + /// Divider active color. + @IBInspectable open var dividerActiveColor = Color.blue.base { - didSet { + didSet { guard isEditing else { return } dividerColor = dividerActiveColor - } - } - - /// The placeholderLabel font value. - @IBInspectable + } + } + + /// The placeholderLabel font value. + @IBInspectable open override var font: UIFont? { - didSet { - placeholderLabel.font = font - } - } - - /// The placeholderLabel text value. - @IBInspectable + didSet { + placeholderLabel.font = font + } + } + + /// The placeholderLabel text value. + @IBInspectable open override var placeholder: String? { - get { - return placeholderLabel.text - } - set(value) { - placeholderLabel.text = value + get { + return placeholderLabel.text + } + set(value) { + if isEditing && isPlaceholderUppercasedWhenEditing { + placeholderLabel.text = value?.uppercased() + } else { + placeholderLabel.text = value + } layoutSubviews() - } - } - - /// The placeholder UILabel. - @IBInspectable + } + } + + /// The placeholder UILabel. + @IBInspectable open let placeholderLabel = UILabel() - - /// Placeholder normal text - @IBInspectable + + /// Placeholder normal text + @IBInspectable open var placeholderNormalColor = Color.darkText.others { - didSet { + didSet { updatePlaceholderLabelColor() - } - } - - /// Placeholder active text - @IBInspectable + } + } + + /// Placeholder active text + @IBInspectable open var placeholderActiveColor = Color.blue.base { - didSet { + didSet { updatePlaceholderLabelColor() - } - } + } + } /// This property adds a padding to placeholder y position animation @IBInspectable open var placeholderVerticalOffset: CGFloat = 0 + + /// This property adds a padding to placeholder y position animation + @IBInspectable + open var placeholderHorizontalOffset: CGFloat = 0 + /// The scale of the active placeholder in relation to the inactive + @IBInspectable + open var placeholderActiveScale: CGFloat = 0.75 { + didSet { + layoutPlaceholderLabel() + } + } + /// The detailLabel UILabel that is displayed. @IBInspectable open let detailLabel = UILabel() @@ -220,53 +247,53 @@ open class TextField: UITextField { /// The detailLabel text value. @IBInspectable open var detail: String? { - get { - return detailLabel.text - } - set(value) { - detailLabel.text = value + get { + return detailLabel.text + } + set(value) { + detailLabel.text = value layoutSubviews() - } - } - - /// Detail text - @IBInspectable + } + } + + /// Detail text + @IBInspectable open var detailColor = Color.darkText.others { - didSet { + didSet { updateDetailLabelColor() - } - } + } + } - /// Vertical distance for the detailLabel from the divider. - @IBInspectable + /// Vertical distance for the detailLabel from the divider. + @IBInspectable open var detailVerticalOffset: CGFloat = 8 { - didSet { - layoutDetailLabel() - } - } - - /// Handles the textAlignment of the placeholderLabel. - open override var textAlignment: NSTextAlignment { - get { - return super.textAlignment - } - set(value) { - super.textAlignment = value - placeholderLabel.textAlignment = value - detailLabel.textAlignment = value - } - } - + didSet { + layoutDetailLabel() + } + } + + /// Handles the textAlignment of the placeholderLabel. + open override var textAlignment: NSTextAlignment { + get { + return super.textAlignment + } + set(value) { + super.textAlignment = value + placeholderLabel.textAlignment = value + detailLabel.textAlignment = value + } + } + /// A reference to the clearIconButton. open fileprivate(set) var clearIconButton: IconButton? - /// Enables the clearIconButton. - @IBInspectable + /// Enables the clearIconButton. + @IBInspectable open var isClearIconButtonEnabled: Bool { - get { - return nil != clearIconButton - } - set(value) { + get { + return nil != clearIconButton + } + set(value) { guard value else { clearIconButton?.removeTarget(self, action: #selector(handleClearIconButton), for: .touchUpInside) clearIconButton = nil @@ -283,36 +310,36 @@ open class TextField: UITextField { clearButtonMode = .never rightViewMode = .whileEditing rightView = clearIconButton - isClearIconButtonAutoHandled = isClearIconButtonAutoHandled ? true : false + isClearIconButtonAutoHandled = { isClearIconButtonAutoHandled }() layoutSubviews() - } - } - - /// Enables the automatic handling of the clearIconButton. - @IBInspectable + } + } + + /// Enables the automatic handling of the clearIconButton. + @IBInspectable open var isClearIconButtonAutoHandled = true { - didSet { - clearIconButton?.removeTarget(self, action: #selector(handleClearIconButton), for: .touchUpInside) - + didSet { + clearIconButton?.removeTarget(self, action: #selector(handleClearIconButton), for: .touchUpInside) + guard isClearIconButtonAutoHandled else { return - } + } clearIconButton?.addTarget(self, action: #selector(handleClearIconButton), for: .touchUpInside) - } - } + } + } /// A reference to the visibilityIconButton. open fileprivate(set) var visibilityIconButton: IconButton? - - /// Enables the visibilityIconButton. - @IBInspectable + + /// Enables the visibilityIconButton. + @IBInspectable open var isVisibilityIconButtonEnabled: Bool { - get { - return nil != visibilityIconButton - } - set(value) { + get { + return nil != visibilityIconButton + } + set(value) { guard value else { visibilityIconButton?.removeTarget(self, action: #selector(handleVisibilityIconButton), for: .touchUpInside) visibilityIconButton = nil @@ -330,108 +357,125 @@ open class TextField: UITextField { clearButtonMode = .never rightViewMode = .whileEditing rightView = visibilityIconButton - isVisibilityIconButtonAutoHandled = isVisibilityIconButtonAutoHandled ? true : false + isVisibilityIconButtonAutoHandled = { isVisibilityIconButtonAutoHandled }() layoutSubviews() - } - } + } + } /// Enables the automatic handling of the visibilityIconButton. @IBInspectable - open var isVisibilityIconButtonAutoHandled: Bool = true { + open var isVisibilityIconButtonAutoHandled = true { didSet { visibilityIconButton?.removeTarget(self, action: #selector(handleVisibilityIconButton), for: .touchUpInside) - guard isVisibilityIconButtonAutoHandled else { return - } + } visibilityIconButton?.addTarget(self, action: #selector(handleVisibilityIconButton), for: .touchUpInside) - } - } - + } + } + + @IBInspectable + open var isPlaceholderUppercasedWhenEditing = false { + didSet { + updatePlaceholderTextToActiveState() + } + } + /** An initializer that initializes the object with a NSCoder object. - Parameter aDecoder: A NSCoder instance. */ - public required init?(coder aDecoder: NSCoder) { - super.init(coder: aDecoder) - prepare() - } - - /** + public required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + prepare() + } + + /** An initializer that initializes the object with a CGRect object. If AutoLayout is used, it is better to initilize the instance using the init() initializer. - Parameter frame: A CGRect instance. */ - public override init(frame: CGRect) { - super.init(frame: frame) - prepare() - } - - /// A convenience initializer. - public convenience init() { - self.init(frame: .zero) - } - - open override func layoutSubviews() { - super.layoutSubviews() + public override init(frame: CGRect) { + super.init(frame: frame) + prepare() + } + + /// A convenience initializer. + public convenience init() { + self.init(frame: .zero) + } + + open override func layoutSubviews() { + super.layoutSubviews() layoutShape() - reload() - } - + layoutPlaceholderLabel() + layoutDetailLabel() + layoutButton(button: clearIconButton) + layoutButton(button: visibilityIconButton) + layoutDivider() + layoutLeftView() + } + open override func becomeFirstResponder() -> Bool { layoutSubviews() return super.becomeFirstResponder() } - /** + /// EdgeInsets for text. + open var textInset: CGFloat = 0 + + open override func textRect(forBounds bounds: CGRect) -> CGRect { + var b = super.textRect(forBounds: bounds) + b.origin.x += textInset + b.size.width -= textInset + return b + } + + open override func editingRect(forBounds bounds: CGRect) -> CGRect { + return textRect(forBounds: bounds) + } + + /** Prepares the view instance when intialized. When subclassing, it is recommended to override the prepare method to initialize property values and other setup operations. The super.prepare method should always be called immediately when subclassing. */ - open func prepare() { - clipsToBounds = false - borderStyle = .none - backgroundColor = nil - contentScaleFactor = Screen.scale + open func prepare() { + clipsToBounds = false + borderStyle = .none + backgroundColor = nil + contentScaleFactor = Screen.scale + font = RobotoFont.regular(with: 16) + textColor = Color.darkText.primary prepareDivider() - preparePlaceholderLabel() - prepareDetailLabel() - prepareTargetHandlers() + preparePlaceholderLabel() + prepareDetailLabel() + prepareTargetHandlers() prepareTextAlignment() - } - - /// Ensures that the components are sized correctly. - open func reload() { - layoutPlaceholderLabel() - layoutDetailLabel() - layoutButton(button: clearIconButton) - layoutButton(button: visibilityIconButton) - layoutDivider() - layoutLeftView() } } -extension TextField { +fileprivate extension TextField { /// Prepares the divider. - fileprivate func prepareDivider() { + func prepareDivider() { dividerColor = dividerNormalColor } /// Prepares the placeholderLabel. - fileprivate func preparePlaceholderLabel() { - font = RobotoFont.regular(with: 16) + func preparePlaceholderLabel() { placeholderNormalColor = Color.darkText.others + placeholderLabel.backgroundColor = .clear addSubview(placeholderLabel) } /// Prepares the detailLabel. - fileprivate func prepareDetailLabel() { + func prepareDetailLabel() { detailLabel.font = RobotoFont.regular(with: 12) detailLabel.numberOfLines = 0 detailColor = Color.darkText.others @@ -439,63 +483,90 @@ extension TextField { } /// Prepares the leftView. - fileprivate func prepareLeftView() { + func prepareLeftView() { leftView?.contentMode = .left + leftViewMode = .always updateLeftViewColor() } /// Prepares the target handlers. - fileprivate func prepareTargetHandlers() { + func prepareTargetHandlers() { addTarget(self, action: #selector(handleEditingDidBegin), for: .editingDidBegin) addTarget(self, action: #selector(handleEditingChanged), for: .editingChanged) addTarget(self, action: #selector(handleEditingDidEnd), for: .editingDidEnd) } /// Prepares the textAlignment. - fileprivate func prepareTextAlignment() { + func prepareTextAlignment() { textAlignment = .rightToLeft == Application.userInterfaceLayoutDirection ? .right : .left } } -extension TextField { +fileprivate extension TextField { /// Updates the leftView tint color. - fileprivate func updateLeftViewColor() { + func updateLeftViewColor() { leftView?.tintColor = isEditing ? leftViewActiveColor : leftViewNormalColor } /// Updates the placeholderLabel text color. - fileprivate func updatePlaceholderLabelColor() { + func updatePlaceholderLabelColor() { tintColor = placeholderActiveColor placeholderLabel.textColor = isEditing ? placeholderActiveColor : placeholderNormalColor } + /// Update the placeholder text to the active state. + func updatePlaceholderTextToActiveState() { + guard isPlaceholderUppercasedWhenEditing else { + return + } + + guard isEditing || !isEmpty else { + return + } + + placeholderLabel.text = placeholderLabel.text?.uppercased() + } + + /// Update the placeholder text to the normal state. + func updatePlaceholderTextToNormalState() { + guard isPlaceholderUppercasedWhenEditing else { + return + } + + guard isEmpty else { + return + } + + placeholderLabel.text = placeholderLabel.text?.capitalized + } + /// Updates the detailLabel text color. - fileprivate func updateDetailLabelColor() { + func updateDetailLabelColor() { detailLabel.textColor = detailColor } } -extension TextField { +fileprivate extension TextField { /// Layout the placeholderLabel. - fileprivate func layoutPlaceholderLabel() { - let w = leftViewWidth + func layoutPlaceholderLabel() { + let w = leftViewWidth + textInset let h = 0 == height ? intrinsicContentSize.height : height placeholderLabel.transform = CGAffineTransform.identity guard isEditing || !isEmpty || !isPlaceholderAnimated else { - placeholderLabel.frame = CGRect(x: w, y: 0, width: width - w, height: h) + placeholderLabel.frame = CGRect(x: w, y: 0, width: width - leftViewWidth - 2 * textInset, height: h) return } - placeholderLabel.frame = CGRect(x: w, y: 0, width: width - w, height: h) - placeholderLabel.transform = CGAffineTransform(scaleX: 0.75, y: 0.75) + placeholderLabel.frame = CGRect(x: w, y: 0, width: width - leftViewWidth - 2 * textInset, height: h) + placeholderLabel.transform = CGAffineTransform(scaleX: placeholderActiveScale, y: placeholderActiveScale) switch textAlignment { case .left, .natural: - placeholderLabel.x = w + placeholderLabel.x = w + placeholderHorizontalOffset case .right: - placeholderLabel.x = width - placeholderLabel.width + placeholderLabel.x = width - placeholderLabel.width - textInset + placeholderHorizontalOffset default:break } @@ -503,26 +574,21 @@ extension TextField { } /// Layout the detailLabel. - fileprivate func layoutDetailLabel() { + func layoutDetailLabel() { let c = dividerContentEdgeInsets - detailLabel.height = detailLabel.sizeThatFits(CGSize(width: width, height: CGFloat.greatestFiniteMagnitude)).height + detailLabel.height = detailLabel.sizeThatFits(CGSize(width: width, height: .greatestFiniteMagnitude)).height detailLabel.x = c.left detailLabel.y = height + detailVerticalOffset detailLabel.width = width - c.left - c.right } /// Layout the a button. - fileprivate func layoutButton(button: UIButton?) { + func layoutButton(button: UIButton?) { button?.frame = CGRect(x: width - height, y: 0, width: height, height: height) } - /// Layout the divider. - fileprivate func layoutDivider() { - divider.reload() - } - /// Layout the leftView. - fileprivate func layoutLeftView() { + func layoutLeftView() { guard let v = leftView else { return } @@ -533,25 +599,24 @@ extension TextField { } } -extension TextField { +fileprivate extension TextField { /// Handles the text editing did begin state. @objc - fileprivate func handleEditingDidBegin() { + func handleEditingDidBegin() { leftViewEditingBeginAnimation() placeholderEditingDidBeginAnimation() dividerEditingDidBeginAnimation() - } // Live updates the textField text. @objc - fileprivate func handleEditingChanged(textField: UITextField) { + func handleEditingChanged(textField: UITextField) { (delegate as? TextFieldDelegate)?.textField?(textField: self, didChange: textField.text) } /// Handles the text editing did end state. @objc - fileprivate func handleEditingDidEnd() { + func handleEditingDidEnd() { leftViewEditingEndAnimation() placeholderEditingDidEndAnimation() dividerEditingDidEndAnimation() @@ -559,7 +624,7 @@ extension TextField { /// Handles the clearIconButton TouchUpInside event. @objc - fileprivate func handleClearIconButton() { + func handleClearIconButton() { guard nil == delegate?.textFieldShouldClear || true == delegate?.textFieldShouldClear?(self) else { return } @@ -575,7 +640,7 @@ extension TextField { /// Handles the visibilityIconButton TouchUpInside event. @objc - fileprivate func handleVisibilityIconButton() { + func handleVisibilityIconButton() { isSecureTextEntry = !isSecureTextEntry if !isSecureTextEntry { @@ -620,10 +685,12 @@ extension TextField { updatePlaceholderLabelColor() guard isPlaceholderAnimated else { + updatePlaceholderTextToActiveState() return } guard isEmpty else { + updatePlaceholderTextToActiveState() return } @@ -632,13 +699,15 @@ extension TextField { return } - s.placeholderLabel.transform = CGAffineTransform(scaleX: 0.75, y: 0.75) + s.placeholderLabel.transform = CGAffineTransform(scaleX: s.placeholderActiveScale, y: s.placeholderActiveScale) + s.updatePlaceholderTextToActiveState() + switch s.textAlignment { case .left, .natural: - s.placeholderLabel.x = s.leftViewWidth + s.placeholderLabel.x = s.leftViewWidth + s.textInset + s.placeholderHorizontalOffset case .right: - s.placeholderLabel.x = s.width - s.placeholderLabel.width + s.placeholderLabel.x = s.width - s.placeholderLabel.width - s.textInset + s.placeholderHorizontalOffset default:break } @@ -654,6 +723,7 @@ extension TextField { } updatePlaceholderLabelColor() + updatePlaceholderTextToNormalState() guard isPlaceholderAnimated else { return @@ -669,7 +739,7 @@ extension TextField { } s.placeholderLabel.transform = CGAffineTransform.identity - s.placeholderLabel.x = s.leftViewWidth + s.placeholderLabel.x = s.leftViewWidth + s.textInset s.placeholderLabel.y = 0 }) } diff --git a/Example/Pods/Material/Sources/iOS/TextStorage.swift b/Example/Pods/Material/Sources/iOS/TextStorage.swift index 582cb0d..d6ab140 100644 --- a/Example/Pods/Material/Sources/iOS/TextStorage.swift +++ b/Example/Pods/Material/Sources/iOS/TextStorage.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/Example/Pods/Material/Sources/iOS/TextView.swift b/Example/Pods/Material/Sources/iOS/TextView.swift index c3ce376..fd53fab 100644 --- a/Example/Pods/Material/Sources/iOS/TextView.swift +++ b/Example/Pods/Material/Sources/iOS/TextView.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,10 +31,74 @@ import UIKit @objc(TextViewDelegate) -public protocol TextViewDelegate : UITextViewDelegate {} +public protocol TextViewDelegate : UITextViewDelegate { + /** + A delegation method that is executed when the keyboard will open. + - Parameter textView: A TextView. + - Parameter willShowKeyboard value: A NSValue. + */ + @objc + optional func textView(textView: TextView, willShowKeyboard value: NSValue) + + /** + A delegation method that is executed when the keyboard will close. + - Parameter textView: A TextView. + - Parameter willHideKeyboard value: A NSValue. + */ + @objc + optional func textView(textView: TextView, willHideKeyboard value: NSValue) + + /** + A delegation method that is executed when the keyboard did open. + - Parameter textView: A TextView. + - Parameter didShowKeyboard value: A NSValue. + */ + @objc + optional func textView(textView: TextView, didShowKeyboard value: NSValue) + + /** + A delegation method that is executed when the keyboard did close. + - Parameter textView: A TextView. + - Parameter didHideKeyboard value: A NSValue. + */ + @objc + optional func textView(textView: TextView, didHideKeyboard value: NSValue) + + /** + A delegation method that is executed when text will be + processed during editing. + - Parameter textView: A TextView. + - Parameter willProcessEditing textStorage: A TextStorage. + - Parameter text: A String. + - Parameter range: A NSRange. + */ + @objc + optional func textView(textView: TextView, willProcessEditing textStorage: TextStorage, text: String, range: NSRange) + + /** + A delegation method that is executed when text has been + processed after editing. + - Parameter textView: A TextView. + - Parameter didProcessEditing textStorage: A TextStorage. + - Parameter text: A String. + - Parameter range: A NSRange. + */ + @objc + optional func textView(textView: TextView, didProcessEditing textStorage: TextStorage, text: String, range: NSRange) +} -@objc(TextView) open class TextView: UITextView { + /// A boolean indicating whether the text is empty. + open var isEmpty: Bool { + return 0 == text?.utf16.count + } + + /// A boolean indicating whether the text is in edit mode. + open fileprivate(set) var isEditing = true + + /// Is the keyboard hidden. + open fileprivate(set) var isKeyboardHidden = true + /// A property that accesses the backing layer's background @IBInspectable open override var backgroundColor: UIColor? { @@ -42,268 +106,339 @@ open class TextView: UITextView { layer.backgroundColor = backgroundColor?.cgColor } } + + /// The placeholderLabel font value. + @IBInspectable + open override var font: UIFont? { + didSet { + placeholderLabel.font = font + } + } + + /// The placeholderLabel text value. + @IBInspectable + open var placeholder: String? { + get { + return placeholderLabel.text + } + set(value) { + placeholderLabel.text = value + } + } + + /// The placeholder UILabel. + @IBInspectable + open let placeholderLabel = UILabel() + + /// Placeholder normal text + @IBInspectable + open var placeholderColor = Color.darkText.others { + didSet { + updatePlaceholderLabelColor() + } + } + + /// NSTextContainer EdgeInsets preset property. + open var textContainerInsetsPreset = EdgeInsetsPreset.none { + didSet { + textContainerInsets = EdgeInsetsPresetToValue(preset: textContainerInsetsPreset) + } + } + + /// NSTextContainer EdgeInsets property. + open var textContainerInsets: EdgeInsets { + get { + return textContainerInset + } + set(value) { + textContainerInset = value + } + } /** - The title UILabel that is displayed when there is text. The - titleLabel text value is updated with the placeholderLabel - text value before being displayed. - */ - @IBInspectable - open var titleLabel: UILabel? { - didSet { - prepareTitleLabel() - } - } - - /// The color of the titleLabel text when the textView is not active. - @IBInspectable - open var titleLabelColor: UIColor? { - didSet { - titleLabel?.textColor = titleLabelColor - } - } - - /// The color of the titleLabel text when the textView is active. - @IBInspectable - open var titleLabelActiveColor: UIColor? - - /** - A property that sets the distance between the textView and - titleLabel. - */ - @IBInspectable - open var titleLabelAnimationDistance: CGFloat = 8 - - /// Placeholder UILabel view. - open var placeholderLabel: UILabel? { - didSet { - preparePlaceholderLabel() - } - } - - /// An override to the text property. - @IBInspectable - open override var text: String! { - didSet { - handleTextViewTextDidChange() - } - } - - /// An override to the attributedText property. - open override var attributedText: NSAttributedString! { - didSet { - handleTextViewTextDidChange() - } - } - - /** - Text container UIEdgeInset preset property. This updates the - textContainerInset property with a preset value. - */ - open var textContainerEdgeInsetsPreset: EdgeInsetsPreset = .none { - didSet { - textContainerInset = EdgeInsetsPresetToValue(preset: textContainerEdgeInsetsPreset) - } - } - - /// Text container UIEdgeInset property. - open override var textContainerInset: EdgeInsets { - didSet { - reload() - } - } - - /** - An initializer that initializes the object with a NSCoder object. - - Parameter aDecoder: A NSCoder instance. - */ + An initializer that initializes the object with a NSCoder object. + - Parameter aDecoder: A NSCoder instance. + */ public required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) prepare() } + + /// The string pattern to match within the textStorage. + open var pattern = "(^|\\s)#[\\d\\w_\u{203C}\u{2049}\u{20E3}\u{2122}\u{2139}\u{2194}-\u{2199}\u{21A9}-\u{21AA}\u{231A}-\u{231B}\u{23E9}-\u{23EC}\u{23F0}\u{23F3}\u{24C2}\u{25AA}-\u{25AB}\u{25B6}\u{25C0}\u{25FB}-\u{25FE}\u{2600}-\u{2601}\u{260E}\u{2611}\u{2614}-\u{2615}\u{261D}\u{263A}\u{2648}-\u{2653}\u{2660}\u{2663}\u{2665}-\u{2666}\u{2668}\u{267B}\u{267F}\u{2693}\u{26A0}-\u{26A1}\u{26AA}-\u{26AB}\u{26BD}-\u{26BE}\u{26C4}-\u{26C5}\u{26CE}\u{26D4}\u{26EA}\u{26F2}-\u{26F3}\u{26F5}\u{26FA}\u{26FD}\u{2702}\u{2705}\u{2708}-\u{270C}\u{270F}\u{2712}\u{2714}\u{2716}\u{2728}\u{2733}-\u{2734}\u{2744}\u{2747}\u{274C}\u{274E}\u{2753}-\u{2755}\u{2757}\u{2764}\u{2795}-\u{2797}\u{27A1}\u{27B0}\u{2934}-\u{2935}\u{2B05}-\u{2B07}\u{2B1B}-\u{2B1C}\u{2B50}\u{2B55}\u{3030}\u{303D}\u{3297}\u{3299}\u{1F004}\u{1F0CF}\u{1F170}-\u{1F171}\u{1F17E}-\u{1F17F}\u{1F18E}\u{1F191}-\u{1F19A}\u{1F1E7}-\u{1F1EC}\u{1F1EE}-\u{1F1F0}\u{1F1F3}\u{1F1F5}\u{1F1F7}-\u{1F1FA}\u{1F201}-\u{1F202}\u{1F21A}\u{1F22F}\u{1F232}-\u{1F23A}\u{1F250}-\u{1F251}\u{1F300}-\u{1F320}\u{1F330}-\u{1F335}\u{1F337}-\u{1F37C}\u{1F380}-\u{1F393}\u{1F3A0}-\u{1F3C4}\u{1F3C6}-\u{1F3CA}\u{1F3E0}-\u{1F3F0}\u{1F400}-\u{1F43E}\u{1F440}\u{1F442}-\u{1F4F7}\u{1F4F9}-\u{1F4FC}\u{1F500}-\u{1F507}\u{1F509}-\u{1F53D}\u{1F550}-\u{1F567}\u{1F5FB}-\u{1F640}\u{1F645}-\u{1F64F}\u{1F680}-\u{1F68A}]+" { + didSet { + prepareRegularExpression() + } + } + + /// A reference to the textView text. + open override var text: String! { + didSet { + setContentOffset(.zero, animated: true) + updatePlaceholderVisibility() + } + } + + /** + A convenience property that accesses the textStorage + string. + */ + open var string: String { + return textStorage.string + } + + /// An Array of matches that match the pattern expression. + open var matches: [String] { + guard let v = (textStorage as? TextStorage)?.expression else { + return [] + } + + return v.matches(in: string, options: [], range: NSMakeRange(0, string.utf16.count)).map { [unowned self] in + (self.string as NSString).substring(with: $0.range).trimmed + } + } + + /** + An Array of unique matches that match the pattern + expression. + */ + open var uniqueMatches: [String] { + var set = Set() + for x in matches { + set.insert(x) + } + return Array(set) + } /** - An initializer that initializes the object with a CGRect object. - If AutoLayout is used, it is better to initilize the instance - using the init() initializer. - - Parameter frame: A CGRect instance. - - Parameter textContainer: A NSTextContainer instance. - */ + An initializer that initializes the object with a CGRect object. + If AutoLayout is used, it is better to initilize the instance + using the init() initializer. + - Parameter frame: A CGRect instance. + - Parameter textContainer: A NSTextContainer instance. + */ public override init(frame: CGRect, textContainer: NSTextContainer?) { super.init(frame: frame, textContainer: textContainer) prepare() } /** - A convenience initializer that is mostly used with AutoLayout. - - Parameter textContainer: A NSTextContainer instance. - */ + A convenience initializer that is mostly used with AutoLayout. + - Parameter textContainer: A NSTextContainer instance. + */ public convenience init(textContainer: NSTextContainer?) { self.init(frame: .zero, textContainer: textContainer) } + + /// A convenience initializer that constructs all aspects of the textView. + public convenience init() { + let textContainer = NSTextContainer(size: .zero) + + let layoutManager = NSLayoutManager() + layoutManager.addTextContainer(textContainer) + + let textStorage = TextStorage() + textStorage.addLayoutManager(layoutManager) + + self.init(textContainer: textContainer) + + textContainer.size = bounds.size + textStorage.delegate = self + } - /** Denitializer. This should never be called unless you know - what you are doing. - */ + /// Denitializer. deinit { - removeNotificationHandlers() + NotificationCenter.default.removeObserver(self) } open override func layoutSubviews() { super.layoutSubviews() layoutShape() layoutShadowPath() - - placeholderLabel?.preferredMaxLayoutWidth = textContainer.size.width - textContainer.lineFragmentPadding * 2 - titleLabel?.frame.size.width = bounds.width + layoutPlaceholderLabel() } - /// Reloads necessary components when the view has changed. - open func reload() { - if let p = placeholderLabel { - removeConstraints(constraints) - layout(p).edges( - top: textContainerInset.top, - left: textContainerInset.left + textContainer.lineFragmentPadding, - bottom: textContainerInset.bottom, - right: textContainerInset.right + textContainer.lineFragmentPadding) - } + /** + Prepares the view instance when intialized. When subclassing, + it is recommended to override the prepare method + to initialize property values and other setup operations. + The super.prepare method should always be called immediately + when subclassing. + */ + open func prepare() { + contentScaleFactor = Screen.scale + textContainerInset = .zero + backgroundColor = nil + font = RobotoFont.regular(with: 16) + textColor = Color.darkText.primary + + prepareNotificationHandlers() + prepareRegularExpression() + preparePlaceholderLabel() } - - /// Notification handler for when text editing began. +} + +fileprivate extension TextView { + /// Prepares the Notification handlers. + func prepareNotificationHandlers() { + let defaultCenter = NotificationCenter.default + defaultCenter.addObserver(self, selector: #selector(handleKeyboardWillShow(notification:)), name: .UIKeyboardWillShow, object: nil) + defaultCenter.addObserver(self, selector: #selector(handleKeyboardWillHide(notification:)), name: .UIKeyboardWillHide, object: nil) + defaultCenter.addObserver(self, selector: #selector(handleKeyboardDidShow(notification:)), name: .UIKeyboardDidShow, object: nil) + defaultCenter.addObserver(self, selector: #selector(handleKeyboardDidHide(notification:)), name: .UIKeyboardDidHide, object: nil) + defaultCenter.addObserver(self, selector: #selector(handleTextViewTextDidBegin), name: .UITextViewTextDidBeginEditing, object: self) + defaultCenter.addObserver(self, selector: #selector(handleTextViewTextDidChange), name: .UITextViewTextDidChange, object: self) + defaultCenter.addObserver(self, selector: #selector(handleTextViewTextDidEnd), name: .UITextViewTextDidEndEditing, object: self) + } + + /// Prepares the regular expression for matching. + func prepareRegularExpression() { + (textStorage as? TextStorage)?.expression = try? NSRegularExpression(pattern: pattern, options: []) + } + + /// prepares the placeholderLabel property. + func preparePlaceholderLabel() { + placeholderLabel.textColor = Color.darkText.others + placeholderLabel.textAlignment = textAlignment + placeholderLabel.numberOfLines = 0 + placeholderLabel.backgroundColor = .clear + addSubview(placeholderLabel) + } +} + +fileprivate extension TextView { + /// Updates the placeholderLabel text color. + func updatePlaceholderLabelColor() { + tintColor = placeholderColor + placeholderLabel.textColor = placeholderColor + } + + /// Updates the placeholderLabel visibility. + func updatePlaceholderVisibility() { + placeholderLabel.isHidden = !isEmpty + } +} + +fileprivate extension TextView { + /// Laysout the placeholder UILabel. + func layoutPlaceholderLabel() { + placeholderLabel.preferredMaxLayoutWidth = textContainer.size.width - textContainer.lineFragmentPadding * 2 + + let x = textContainerInset.left + textContainer.lineFragmentPadding + let y = textContainerInset.top + placeholderLabel.sizeToFit() + + placeholderLabel.frame.origin.x = x + placeholderLabel.frame.origin.y = y + placeholderLabel.frame.size.width = textContainer.size.width - textContainerInset.right - textContainer.lineFragmentPadding + } +} + +fileprivate extension TextView { + /** + Handler for when the keyboard will open. + - Parameter notification: A Notification. + */ @objc - fileprivate func handleTextViewTextDidBegin() { - titleLabel?.textColor = titleLabelActiveColor - } - - /// Notification handler for when text changed. - @objc - fileprivate func handleTextViewTextDidChange() { - if let p = placeholderLabel { - p.isHidden = !(true == text?.isEmpty) - } - - guard let t = text else { - hideTitleLabel() + func handleKeyboardWillShow(notification: Notification) { + guard isKeyboardHidden else { return } - if 0 < t.utf16.count { - showTitleLabel() - } else { - hideTitleLabel() + guard let v = notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue else { + return } - } - - /// Notification handler for when text editing ended. + + (delegate as? TextViewDelegate)?.textView?(textView: self, willShowKeyboard: v) + } + + /** + Handler for when the keyboard did open. + - Parameter notification: A Notification. + */ @objc - fileprivate func handleTextViewTextDidEnd() { - guard let t = text else { - hideTitleLabel() + func handleKeyboardDidShow(notification: Notification) { + guard isKeyboardHidden else { return } - if 0 < t.utf16.count { - showTitleLabel() - } else { - hideTitleLabel() + isKeyboardHidden = false + + guard let v = notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue else { + return } - titleLabel?.textColor = titleLabelColor - } - - /** - Prepares the view instance when intialized. When subclassing, - it is recommended to override the prepare method - to initialize property values and other setup operations. - The super.prepare method should always be called immediately - when subclassing. + (delegate as? TextViewDelegate)?.textView?(textView: self, didShowKeyboard: v) + } + + /** + Handler for when the keyboard will close. + - Parameter notification: A Notification. */ - open func prepare() { - contentScaleFactor = Screen.scale - textContainerInset = .zero - backgroundColor = .white - clipsToBounds = false - removeNotificationHandlers() - prepareNotificationHandlers() - reload() - } - - /// prepares the placeholderLabel property. - fileprivate func preparePlaceholderLabel() { - if let v: UILabel = placeholderLabel { - v.font = font - v.textAlignment = textAlignment - v.numberOfLines = 0 - v.backgroundColor = .clear - addSubview(v) - reload() - handleTextViewTextDidChange() - } - } - - /// Prepares the titleLabel property. - fileprivate func prepareTitleLabel() { - if let v: UILabel = titleLabel { - v.isHidden = true - addSubview(v) - - guard let t = text, 0 == t.utf16.count else { - v.alpha = 0 - return - } - - showTitleLabel() - } - } - - /// Shows and animates the titleLabel property. - fileprivate func showTitleLabel() { - if let v: UILabel = titleLabel { - if v.isHidden { - if let s: String = placeholderLabel?.text { - v.text = s - } - let h: CGFloat = ceil(v.font.lineHeight) - v.frame = CGRect(x: 0, y: -h, width: bounds.width, height: h) - v.isHidden = false - UIView.animate(withDuration: 0.25, animations: { [weak self] in - if let s: TextView = self { - v.alpha = 1 - v.frame.origin.y = -v.frame.height - s.titleLabelAnimationDistance - } - }) - } - } - } - - /// Hides and animates the titleLabel property. - fileprivate func hideTitleLabel() { - if let v: UILabel = titleLabel { - if !v.isHidden { - UIView.animate(withDuration: 0.25, animations: { - v.alpha = 0 - v.frame.origin.y = -v.frame.height - }) { _ in - v.isHidden = true - } - } - } - } - - /// Prepares the Notification handlers. - fileprivate func prepareNotificationHandlers() { - let defaultCenter = NotificationCenter.default - defaultCenter.addObserver(self, selector: #selector(handleTextViewTextDidBegin), name: NSNotification.Name.UITextViewTextDidBeginEditing, object: self) - defaultCenter.addObserver(self, selector: #selector(handleTextViewTextDidChange), name: NSNotification.Name.UITextViewTextDidChange, object: self) - defaultCenter.addObserver(self, selector: #selector(handleTextViewTextDidEnd), name: NSNotification.Name.UITextViewTextDidEndEditing, object: self) - } - - /// Removes the Notification handlers. - fileprivate func removeNotificationHandlers() { - let defaultCenter = NotificationCenter.default - defaultCenter.removeObserver(self, name: NSNotification.Name.UITextViewTextDidBeginEditing, object: self) - defaultCenter.removeObserver(self, name: NSNotification.Name.UITextViewTextDidChange, object: self) - defaultCenter.removeObserver(self, name: NSNotification.Name.UITextViewTextDidEndEditing, object: self) - } + @objc + func handleKeyboardWillHide(notification: Notification) { + guard !isKeyboardHidden else { + return + } + + guard let v = notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue else { + return + } + + (delegate as? TextViewDelegate)?.textView?(textView: self, willHideKeyboard: v) + } + + /** + Handler for when the keyboard did close. + - Parameter notification: A Notification. + */ + @objc + func handleKeyboardDidHide(notification: Notification) { + guard !isKeyboardHidden else { + return + } + + isKeyboardHidden = true + + guard let v = notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue else { + return + } + + (delegate as? TextViewDelegate)?.textView?(textView: self, didHideKeyboard: v) + } + + /// Notification handler for when text editing began. + @objc + func handleTextViewTextDidBegin() { + isEditing = true + } + + /// Notification handler for when text changed. + @objc + func handleTextViewTextDidChange() { + updatePlaceholderVisibility() + } + + /// Notification handler for when text editing ended. + @objc + func handleTextViewTextDidEnd() { + isEditing = false + updatePlaceholderVisibility() + } +} + +extension TextView: TextStorageDelegate { + @objc + open func textStorage(textStorage: TextStorage, willProcessEditing text: String, range: NSRange) { + (delegate as? TextViewDelegate)?.textView?(textView: self, willProcessEditing: textStorage, text: string, range: range) + } + + @objc + open func textStorage(textStorage: TextStorage, didProcessEditing text: String, result: NSTextCheckingResult?, flags: NSRegularExpression.MatchingFlags, stop: UnsafeMutablePointer) { + guard let range = result?.range else { + return + } + + (delegate as? TextViewDelegate)?.textView?(textView: self, didProcessEditing: textStorage, text: string, range: range) + } } diff --git a/Example/Pods/Material/Sources/iOS/Toolbar.swift b/Example/Pods/Material/Sources/iOS/Toolbar.swift index 3ebf582..43da04f 100644 --- a/Example/Pods/Material/Sources/iOS/Toolbar.swift +++ b/Example/Pods/Material/Sources/iOS/Toolbar.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,7 +30,7 @@ import UIKit -private var ToolbarContext: UInt8 = 0 +fileprivate var ToolbarContext: UInt8 = 0 open class Toolbar: Bar { /// A convenience property to set the titleLabel.text. @@ -95,9 +95,11 @@ open class Toolbar: Bar { contentViewAlignment = .center == titleLabel.textAlignment ? .center : .full } - /// Reloads the view. - open override func reload() { - super.reload() + open override func layoutSubviews() { + super.layoutSubviews() + guard willLayout else { + return + } if nil != title && "" != title { if nil == titleLabel.superview { @@ -133,17 +135,11 @@ open class Toolbar: Bar { } } - /** - Prepares the view instance when intialized. When subclassing, - it is recommended to override the prepare method - to initialize property values and other setup operations. - The super.prepare method should always be called immediately - when subclassing. - */ open override func prepare() { super.prepare() contentViewAlignment = .center - prepareTitleLabel() + + prepareTitleLabel() prepareDetailLabel() } } diff --git a/Example/Pods/Material/Sources/iOS/ToolbarController.swift b/Example/Pods/Material/Sources/iOS/ToolbarController.swift index 46e0112..daf51a1 100644 --- a/Example/Pods/Material/Sources/iOS/ToolbarController.swift +++ b/Example/Pods/Material/Sources/iOS/ToolbarController.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,195 +30,94 @@ import UIKit -extension UIViewController { - /** +@objc(ToolbarAlignment) +public enum ToolbarAlignment: Int { + case top + case bottom +} + +public extension UIViewController { + /** A convenience property that provides access to the ToolbarController. This is the recommended method of accessing the ToolbarController through child UIViewControllers. */ - public var toolbarController: ToolbarController? { - var viewController: UIViewController? = self - while nil != viewController { - if viewController is ToolbarController { - return viewController as? ToolbarController - } - viewController = viewController?.parent - } - return nil - } -} - -@objc(ToolbarControllerDelegate) -public protocol ToolbarControllerDelegate { - /// Delegation method that executes when the floatingViewController will open. - @objc - optional func toolbarControllerWillOpenFloatingViewController(toolbarController: ToolbarController) - - /// Delegation method that executes when the floatingViewController will close. - @objc - optional func toolbarControllerWillCloseFloatingViewController(toolbarController: ToolbarController) - - /// Delegation method that executes when the floatingViewController did open. - @objc - optional func toolbarControllerDidOpenFloatingViewController(toolbarController: ToolbarController) - - /// Delegation method that executes when the floatingViewController did close. - @objc - optional func toolbarControllerDidCloseFloatingViewController(toolbarController: ToolbarController) + var toolbarController: ToolbarController? { + return traverseViewControllerHierarchyForClassType() + } } @objc(ToolbarController) open class ToolbarController: StatusBarController { - /** - A Display value to indicate whether or not to - display the rootViewController to the full view - bounds, or up to the toolbar height. - */ - open var display = Display.partial { + /// Reference to the Toolbar. + @IBInspectable + open let toolbar = Toolbar() + + /// The toolbar alignment. + open var toolbarAlignment = ToolbarAlignment.top { didSet { layoutSubviews() } } - /// Reference to the Toolbar. - @IBInspectable - open let toolbar = Toolbar() - - /// Internal reference to the floatingViewController. - private var internalFloatingViewController: UIViewController? - - /// Delegation handler. - open weak var delegate: ToolbarControllerDelegate? - - /// A floating UIViewController. - open var floatingViewController: UIViewController? { - get { - return internalFloatingViewController - } - set(value) { - if let v = internalFloatingViewController { - v.view.layer.rasterizationScale = Screen.scale - v.view.layer.shouldRasterize = true - delegate?.toolbarControllerWillCloseFloatingViewController?(toolbarController: self) - internalFloatingViewController = nil - UIView.animate(withDuration: 0.5, - animations: { [weak self] in - guard let s = self else { - return - } - - v.view.center.y = 2 * s.view.bounds.height - s.toolbar.alpha = 1 - s.rootViewController.view.alpha = 1 - }) { [weak self] _ in - guard let s = self else { - return - } - - v.willMove(toParentViewController: nil) - v.view.removeFromSuperview() - v.removeFromParentViewController() - v.view.layer.shouldRasterize = false - s.isUserInteractionEnabled = true - s.toolbar.isUserInteractionEnabled = true - DispatchQueue.main.async { [weak self] in - guard let s = self else { - return - } - - s.delegate?.toolbarControllerDidCloseFloatingViewController?(toolbarController: s) - } - } - } - - if let v = value { - // Add the noteViewController! to the view. - addChildViewController(v) - v.view.frame = view.bounds - v.view.center.y = 2 * view.bounds.height - v.view.isHidden = true - view.insertSubview(v.view, aboveSubview: toolbar) - v.view.layer.zPosition = 1500 - v.didMove(toParentViewController: self) - v.view.isHidden = false - v.view.layer.rasterizationScale = Screen.scale - v.view.layer.shouldRasterize = true - view.layer.rasterizationScale = Screen.scale - view.layer.shouldRasterize = true - internalFloatingViewController = v - isUserInteractionEnabled = false - toolbar.isUserInteractionEnabled = false - delegate?.toolbarControllerWillOpenFloatingViewController?(toolbarController: self) - UIView.animate(withDuration: 0.5, - animations: { [weak self, v = v] in - guard let s = self else { - return - } - - v.view.center.y = s.view.bounds.height / 2 - s.toolbar.alpha = 0.5 - s.rootViewController.view.alpha = 0.5 - }) { [weak self, v = v] _ in - guard let s = self else { - return - } - - v.view.layer.shouldRasterize = false - s.view.layer.shouldRasterize = false - DispatchQueue.main.async { [weak self] in - guard let s = self else { - return - } - - s.delegate?.toolbarControllerDidOpenFloatingViewController?(toolbarController: s) - } - } - } - } - } - - - open override func layoutSubviews() { + open override func layoutSubviews() { super.layoutSubviews() - - let y = Application.shouldStatusBarBeHidden || statusBar.isHidden ? 0 : statusBar.height - let p = y + toolbar.height - - toolbar.y = y - toolbar.width = view.width - - switch display { - case .partial: - rootViewController.view.y = p - rootViewController.view.height = view.height - p - case .full: - rootViewController.view.frame = view.bounds - } + layoutToolbar() + layoutContainer() + layoutRootViewController() } - /** - Prepares the view instance when intialized. When subclassing, - it is recommended to override the prepare method - to initialize property values and other setup operations. - The super.prepare method should always be called immediately - when subclassing. - */ open override func prepare() { super.prepare() - prepareStatusBar() + displayStyle = .partial + prepareToolbar() } } -extension ToolbarController { - /// Prepares the statusBar. - fileprivate func prepareStatusBar() { - shouldHideStatusBarOnRotation = false - } - +fileprivate extension ToolbarController { /// Prepares the toolbar. - fileprivate func prepareToolbar() { + func prepareToolbar() { + toolbar.zPosition = 1000 toolbar.depthPreset = .depth1 view.addSubview(toolbar) } } + +fileprivate extension ToolbarController { + /// Layout the container. + func layoutContainer() { + switch displayStyle { + case .partial: + let p = toolbar.height + let q = statusBarOffsetAdjustment + let h = view.height - p - q + + switch toolbarAlignment { + case .top: + container.y = q + p + container.height = h + case .bottom: + container.y = q + container.height = h + } + + container.width = view.width + + case .full: + container.frame = view.bounds + } + } + + /// Layout the toolbar. + func layoutToolbar() { + toolbar.x = 0 + toolbar.y = .top == toolbarAlignment ? statusBarOffsetAdjustment : view.height - toolbar.height + toolbar.width = view.width + } + + /// Layout the rootViewController. + func layoutRootViewController() { + rootViewController.view.frame = container.bounds + } +} diff --git a/Example/Pods/Material/Sources/iOS/RootController.swift b/Example/Pods/Material/Sources/iOS/TransitionController.swift similarity index 58% rename from Example/Pods/Material/Sources/iOS/RootController.swift rename to Example/Pods/Material/Sources/iOS/TransitionController.swift index d4c68fb..8e0ac58 100644 --- a/Example/Pods/Material/Sources/iOS/RootController.swift +++ b/Example/Pods/Material/Sources/iOS/TransitionController.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,129 +30,140 @@ import UIKit -open class RootController: UIViewController { - /** +open class TransitionController: UIViewController { + /** A Boolean property used to enable and disable interactivity with the rootViewController. */ - @IBInspectable + @IBInspectable open var isUserInteractionEnabled: Bool { - get { - return rootViewController.view.isUserInteractionEnabled - } - set(value) { - rootViewController.view.isUserInteractionEnabled = value - } - } - - /** + get { + return rootViewController.view.isUserInteractionEnabled + } + set(value) { + rootViewController.view.isUserInteractionEnabled = value + } + } + + /// A reference to the container view. + @IBInspectable + open let container = UIView() + + /** A UIViewController property that references the active main UIViewController. To swap the rootViewController, it is recommended to use the transitionFromRootViewController helper method. */ - open fileprivate(set) var rootViewController: UIViewController! - - /** + open internal(set) var rootViewController: UIViewController! + + /// The transition type used during a transition. + open var motionTransitionType = MotionTransitionType.fade + + /** An initializer that initializes the object with a NSCoder object. - Parameter aDecoder: A NSCoder instance. */ - public required init?(coder aDecoder: NSCoder) { - super.init(coder: aDecoder) - prepare() - } - - /** + public required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + } + + /** An initializer that initializes the object with an Optional nib and bundle. - Parameter nibNameOrNil: An Optional String for the nib. - Parameter bundle: An Optional NSBundle where the nib is located. */ - public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { - super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) - prepare() - } - - /** + public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { + super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) + } + + /** An initializer for the BarController. - Parameter rootViewController: The main UIViewController. */ - public init(rootViewController: UIViewController) { - super.init(nibName: nil, bundle: nil) - self.rootViewController = rootViewController - prepare() - } - - open override func viewWillLayoutSubviews() { - super.viewWillLayoutSubviews() - layoutSubviews() - } - - /** + public init(rootViewController: UIViewController) { + super.init(nibName: nil, bundle: nil) + self.rootViewController = rootViewController + } + + open override func viewDidLoad() { + super.viewDidLoad() + prepare() + } + + open override func viewWillLayoutSubviews() { + super.viewWillLayoutSubviews() + layoutSubviews() + } + + /** A method to swap rootViewController objects. - Parameter toViewController: The UIViewController to swap with the active rootViewController. - - Parameter duration: A TimeInterval that sets the - animation duration of the transition. - - Parameter options: UIViewAnimationOptions thst are used - when animating the transition from the active rootViewController - to the toViewController. - - Parameter animations: An animation block that is executed during - the transition from the active rootViewController - to the toViewController. - Parameter completion: A completion block that is execited after the transition animation from the active rootViewController to the toViewController has completed. */ - open func transition(to viewController: UIViewController, duration: TimeInterval = 0.5, options: UIViewAnimationOptions = [], animations: (() -> Void)? = nil, completion: ((Bool) -> Void)? = nil) { - rootViewController.willMove(toParentViewController: nil) - addChildViewController(viewController) - viewController.view.frame = rootViewController.view.frame - transition(from: rootViewController, - to: viewController, - duration: duration, - options: options, - animations: animations) { [weak self, viewController = viewController, completion = completion] (result) in - guard let s = self else { - return - } - - viewController.didMove(toParentViewController: s) - s.rootViewController.removeFromParentViewController() - s.rootViewController = viewController - s.rootViewController.view.clipsToBounds = true - s.rootViewController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight] - s.rootViewController.view.contentScaleFactor = Screen.scale - s.view.sendSubview(toBack: s.rootViewController.view) - completion?(result) - } - } - - /** + open func transition(to viewController: UIViewController, completion: ((Bool) -> Void)? = nil) { + guard let fvc = rootViewController else { + return + } + + let tvc = viewController + + tvc.view.isHidden = false + tvc.view.frame = container.bounds + tvc.motionModalTransitionType = motionTransitionType + + view.isUserInteractionEnabled = false + Motion.shared.transition(from: fvc, to: tvc, in: container) { [weak self, tvc = tvc, completion = completion] (isFinished) in + guard let s = self else { + return + } + + s.rootViewController = tvc + s.view.isUserInteractionEnabled = true + completion?(isFinished) + } + } + + /** To execute in the order of the layout chain, override this method. `layoutSubviews` should be called immediately, unless you have a certain need. */ - open func layoutSubviews() {} - - /** + open func layoutSubviews() {} + + /** Prepares the view instance when intialized. When subclassing, it is recommended to override the prepare method to initialize property values and other setup operations. The super.prepare method should always be called immediately when subclassing. */ - open func prepare() { + open func prepare() { view.clipsToBounds = true view.backgroundColor = .white view.contentScaleFactor = Screen.scale + + prepareContainer() prepareRootViewController() - } + } } -extension RootController { +internal extension TransitionController { + /// Prepares the container view. + func prepareContainer() { + container.frame = view.bounds + container.clipsToBounds = true + container.contentScaleFactor = Screen.scale + container.autoresizingMask = [.flexibleWidth, .flexibleHeight] + view.addSubview(container) + } + /// A method that prepares the rootViewController. - internal func prepareRootViewController() { - prepare(viewController: rootViewController, withContainer: view) + func prepareRootViewController() { + prepare(viewController: rootViewController, in: container) } /** @@ -160,10 +171,10 @@ extension RootController { the BarController within the passed in container view. - Parameter viewController: A UIViewController to add as a child. - - Parameter withContainer container: A UIView that is the parent of the + - Parameter in container: A UIView that is the parent of the passed in controller view within the view hierarchy. */ - internal func prepare(viewController: UIViewController?, withContainer container: UIView) { + func prepare(viewController: UIViewController?, in container: UIView) { guard let v = viewController else { return } diff --git a/Example/Pods/Material/Sources/iOS/View.swift b/Example/Pods/Material/Sources/iOS/View.swift index 9790282..47fe5d2 100644 --- a/Example/Pods/Material/Sources/iOS/View.swift +++ b/Example/Pods/Material/Sources/iOS/View.swift @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . + * Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. . * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/Example/Pods/Pods.xcodeproj/project.pbxproj b/Example/Pods/Pods.xcodeproj/project.pbxproj index fc80bb3..0d99a2e 100644 --- a/Example/Pods/Pods.xcodeproj/project.pbxproj +++ b/Example/Pods/Pods.xcodeproj/project.pbxproj @@ -7,393 +7,463 @@ objects = { /* Begin PBXBuildFile section */ - 03496A5A4D098F402532B3083CF1C635 /* View.swift in Sources */ = {isa = PBXBuildFile; fileRef = F6039EE99F67816635C75BE125A56BF2 /* View.swift */; }; - 038467314E74EFFBD0F8B9D99296E12A /* Constraint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 59286B46714772F8B5110C675CA9E4E5 /* Constraint.swift */; }; - 03950C59BF61B33174F4FAE0F3B78C9F /* ConstraintConstantTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8574BF3D0680E8B3FF01479BC6E6030B /* ConstraintConstantTarget.swift */; }; - 041F8818FE29EDD798F46469BC138C3C /* Roboto-Medium.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 137CA1F1B10E4EC527FD79DA09B9A232 /* Roboto-Medium.ttf */; }; - 042A341D388FDD4A6F1ED5BC37520FB6 /* ImageCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF1A2FBEF5874FE986CD9FC93B60615B /* ImageCard.swift */; }; - 0730F0AF3DFBFC1D450004446C6EC95E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CEC22C73C1608DFA5D5D78BDCB218219 /* Foundation.framework */; }; - 085D8569FC69B36C65045B42D8C04908 /* MenuItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = B99D67DEFF46F955A0A4388075807446 /* MenuItem.swift */; }; - 088B9975A92495DD9C802A5B3EFCC0E2 /* ConstraintMakerExtendable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C4D4BD2840EA90650FE252BB9693AE9 /* ConstraintMakerExtendable.swift */; }; - 0E87C93AA24D9B5867D2A76BD6B106DD /* MotionTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = 35816A481311F72E21C7D87A865527A3 /* MotionTransition.swift */; }; - 0EF2BF49EA6B91EFBBF3C1D8E0DA8EB2 /* PresenterCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 060FB1C443967E5FB108D964A3315244 /* PresenterCard.swift */; }; - 108BFFCF9DE940FE68A1462EC3B4EC89 /* Depth.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED42050548213D1CAF29D3ED249A98FF /* Depth.swift */; }; - 1104FB451F79B05DE6F604BB9A263A44 /* DynamicFontType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C22D49D3B14F027CBDEB32F3BB68C732 /* DynamicFontType.swift */; }; - 1603A4DF011F122D27EFF7AE88B3F1B2 /* FabButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22FF2B67C144E96CBCDA8E4B0DBBFB60 /* FabButton.swift */; }; - 161B9A182D426280DEB4A857A1A30643 /* RobotoFont.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6676636F44773FDE40C8FAF6D034419F /* RobotoFont.swift */; }; - 1A2712A32F25B1C2AAFB6A11A93E8D8A /* TextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9BCCE7C2B99E6EAF7C935B30D8099848 /* TextField.swift */; }; - 1F29B801935B0201E36B4837FC8FA309 /* HeightPreset.swift in Sources */ = {isa = PBXBuildFile; fileRef = ECCA7A951804AC16FC98668C19F8A40E /* HeightPreset.swift */; }; - 29EDEA7E8B7BABEE31ED9614AC458A88 /* Color.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DEC520A57ED877D9E44252C8FD75A0B /* Color.swift */; }; - 2A470A43222FD9C00E182536F74EC789 /* ConstraintLayoutGuideDSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 489E7C29FB18995359DF56C6CD587D22 /* ConstraintLayoutGuideDSL.swift */; }; - 2C1349BD5B9128E6ED7F74A2F9EBBBE9 /* TableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56C2CD4361B65A92AF0CD0726C46C22C /* TableViewController.swift */; }; - 314720DDFBEB9586D0E78230356D18C0 /* KeyboardSpyEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = D04E0FAEA80A394C9A0A29DF0BC13409 /* KeyboardSpyEvent.swift */; }; - 31A868B795032F24CE7E4EA25129FF93 /* NavigationBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 188202353462A51F258C407A71543BDF /* NavigationBar.swift */; }; - 332C00ED864DAC5BA34505EB45011F6E /* ConstraintAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E0C2ECC32318E612A2616E4508C446C /* ConstraintAttributes.swift */; }; - 393A6FD40BF13F3F3657200EFF1546BF /* KeyboardSpyAgent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DDDCB0C43CADB19A98F4338101C1168 /* KeyboardSpyAgent.swift */; }; - 3A764EE000FA63AAE897B536AF1B1355 /* CornerRadius.swift in Sources */ = {isa = PBXBuildFile; fileRef = 23C6DA2BCB6964F446E9085159C902AB /* CornerRadius.swift */; }; - 3B8CDD6DB935E882F4D7E4C5B0797D84 /* Shape.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B472103E56AC172D2C0BE714AA81690 /* Shape.swift */; }; - 3BA70F07F971E6F9BCCDFA64596D8976 /* RootController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A183AB8864CA6D36905EFBAFE72328C2 /* RootController.swift */; }; - 3C3A89CC4080B7A8541997E42004AE74 /* TextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 238367CB9EE1D75CA44120096771C5FC /* TextView.swift */; }; - 3D290D86B2D4375A97D90B366146374E /* Switch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48C8DD3ADA21FEC1C19ADACF1DA4DEBD /* Switch.swift */; }; - 3E36BB00F7B283FF631B274034EB0DA9 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CEC22C73C1608DFA5D5D78BDCB218219 /* Foundation.framework */; }; - 3FE2F4127830858BD8FB0E021AAC652F /* ConstraintMakerRelatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 279BD983E3CB70058E72691E62FAB246 /* ConstraintMakerRelatable.swift */; }; - 4045091ABC321CDD36B299EBB874CC55 /* KeyboardSpyInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B68143D947DEF19A7E8AA56B37B7CF9 /* KeyboardSpyInfo.swift */; }; - 408DF434D98C7D0C0B3272F32FD889D4 /* FlatButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD437F3EDD3EA9947C1B479CD2C33F43 /* FlatButton.swift */; }; - 430407820477E1EBA2EC0F4D1B7B558C /* KeyboardSpy.swift in Sources */ = {isa = PBXBuildFile; fileRef = F92385CDBFE17EE69610B27067AC7FCE /* KeyboardSpy.swift */; }; - 4370380B3DAF72486223D4899A6AD6B4 /* Offset.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3A10EE0EC0560A2EC2BFD40D0CF5E18 /* Offset.swift */; }; - 441CB6FD9F500D2F85A2880DF46B0F0D /* StatusBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C4C6087871B4325FCACD7729BCC7142 /* StatusBarController.swift */; }; - 478926EE4EA225BA4D77B57501BAD3DA /* IconButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E8D72D2A07C4CFA4A4B47E70AD6813A /* IconButton.swift */; }; - 4A7F4710D5CC3DD0493A9789B19A44DB /* Card.swift in Sources */ = {isa = PBXBuildFile; fileRef = 11210AFBDE6150A11B9352BE81DB9B59 /* Card.swift */; }; - 4EEE4120445D44C7578CCDB7978930E8 /* MotionKeyframe.swift in Sources */ = {isa = PBXBuildFile; fileRef = D90050DEF76E42795A7B6EF2EF100A07 /* MotionKeyframe.swift */; }; - 51989B46FE335C57B129AC49DC8D83E3 /* SnapKit-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 828D6C8E170FA51D2D89BFEDD3C464F9 /* SnapKit-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 53964849233A438AD05FF49D49786EFA /* Debugging.swift in Sources */ = {isa = PBXBuildFile; fileRef = E22BF5FC7BE90AB43E1CBA18E2376C02 /* Debugging.swift */; }; - 54A631C19A6E4F9A9E75C0EA7938F5B5 /* ErrorTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E3F318769C538096A7AF92767CD5E67 /* ErrorTextField.swift */; }; - 56ACC73D8791BD63CEB2D8EF746C1369 /* LayoutConstraintItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55296E0F08CC0C7F4232ED6333949D70 /* LayoutConstraintItem.swift */; }; - 57B38166C0C692A75708F2A8AE8E6823 /* Device.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48EF6003775C91D21EB500BFDCB49075 /* Device.swift */; }; - 58AB7BD193C92C789799EB5453F226D9 /* Layout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50793AF3E7D68DD48DE992F0E18E7B11 /* Layout.swift */; }; - 596214455316ECE5C1446C8B9D54455F /* Material+UIWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 39CA1D743E25A38354A5D1C016E73BBC /* Material+UIWindow.swift */; }; - 5A30ED864F3C7FF840DB2816EC67BDC4 /* LayoutConstraint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 308A0B595DF71E47E4D305564E1639E3 /* LayoutConstraint.swift */; }; - 5AE8CD3647945C891F5197673BD262AD /* ConstraintMakerFinalizable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50C3D1709D201AB8633D3379DA9EB61D /* ConstraintMakerFinalizable.swift */; }; - 5BF08BFB86CDB5F9ED72D0BF7726EA5F /* CharacterAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = C1741A06B2D81CA2FB171505DB8B09E5 /* CharacterAttribute.swift */; }; - 5ED4F621B9D375DF822FCEB9365DBE52 /* io.cosmicmind.material.icons.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 74D407BF89192F7B53EBC558741601A2 /* io.cosmicmind.material.icons.bundle */; }; - 603CD5E323F371AE272D9A985B5BF498 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CEC22C73C1608DFA5D5D78BDCB218219 /* Foundation.framework */; }; - 62AAA0508EC605D8C0B4CC86BAB2C100 /* Layer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6CF9A0DDB142AF7D40E293FDA149E77 /* Layer.swift */; }; - 64424B8E644C619D74842BC52CB6E6C6 /* PageTabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AA631E65680AB84D04DA6E325AC5149 /* PageTabBarController.swift */; }; - 67764772F5E84D50BDE210ADB104149A /* BottomTabBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1AB532552FB417CAD645F0C6B302AFA3 /* BottomTabBar.swift */; }; - 681BDC2A3825785488941AA42D9145BA /* Snackbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = F29DD185D104269D36618B26571B0522 /* Snackbar.swift */; }; - 68419532AB36559889B118BFDD80B96C /* Pods-KeyboardSpy_Example-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = EE8F4318B6998AD8B763D75C3C2779DD /* Pods-KeyboardSpy_Example-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 68CF79C3AA1EBB59BBFF7426B1102DF1 /* Material+UIFont.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04F5D2F7D208372B8E2D22C1AEEA8424 /* Material+UIFont.swift */; }; - 68DD16A5D31384E22C087BBDCA40845F /* Material+Array.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7FBE2265884984A05086DD251FC5971A /* Material+Array.swift */; }; - 696EBEE205A2F204DCC8A62ADF79A205 /* Screen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EA88863FE5C899F0B300BB6271371DE /* Screen.swift */; }; - 6C2FCFBDD0E47AAEE9D846821463A9F5 /* KeyboardSpy-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = ED97A6BBA65BBA334E662ECA9E02B06E /* KeyboardSpy-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 6E072E60B6F0DE01692443973D67F2C1 /* Button.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8EEAE6D6FDAB8AEF9F638C3F10535D1 /* Button.swift */; }; - 719B3731A3CD3640B2006248EFD9845A /* TabBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9818E677DDAF7ED27910C966923CABEB /* TabBar.swift */; }; - 71B5753CFF85DE929604D8DB75472F3F /* ConstraintViewDSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F3D602E6FBCE343A9F449D13208571B /* ConstraintViewDSL.swift */; }; - 71D84D2CFBD83BFB145F0695ED657868 /* PulseView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01E281BC27F0ADF6A78211E32A61BE7F /* PulseView.swift */; }; - 72C2032BEC3F1EFA654FF30C31527AA0 /* Roboto-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = AA4DA8C856465AF25613B8DE31FA29F9 /* Roboto-Regular.ttf */; }; - 732CE59AC540554CE13017B7A2AE441A /* NavigationDrawerController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF75F63D1E73F0F69739117868966536 /* NavigationDrawerController.swift */; }; - 748C19F532E69EA4343DF40D451B8C1B /* Toolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 613B5985B4FAAAE96C41D1FA839C9831 /* Toolbar.swift */; }; - 74B88CD3CC07EEF0B1E70A800E210EE5 /* ConstraintRelation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 998AD3233A9E4B030C240E4EA3323378 /* ConstraintRelation.swift */; }; - 74BE458E2740DA78698557408BD571A4 /* Icon.swift in Sources */ = {isa = PBXBuildFile; fileRef = 786BC7BB1F427F271C44AD843AE23F6C /* Icon.swift */; }; - 7CA24CCEAB7688344297266563B6D7B4 /* CollectionReusableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 058D958E907406F5AA26CAF6CF734232 /* CollectionReusableView.swift */; }; - 7D624CC1D3D79DA69676897F08166084 /* Grid.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6CAADE0822269FB6362B3FFECAECB42 /* Grid.swift */; }; - 7DC011757098CD63CA38FBA776DA1A33 /* ConstraintLayoutSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 10440FE2C155F716F5B22EAF2558CFD2 /* ConstraintLayoutSupport.swift */; }; - 8031C583A16B689B88139C80BF56347C /* ConstraintInsets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 18E13B7190D852B4061B2763D342560E /* ConstraintInsets.swift */; }; - 80345CB832ECC3486C17FBE5407E9E02 /* ConstraintLayoutGuide.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1508FE4D19F51D57ABD80E4E5DA55A6E /* ConstraintLayoutGuide.swift */; }; - 82DA1092C729308791BAC34352B0DB08 /* EdgeInsets.swift in Sources */ = {isa = PBXBuildFile; fileRef = AD65A1EB0EC10BBA9A12B7702A44BEE1 /* EdgeInsets.swift */; }; - 82E350FFDE42493FB116C516939E8DAF /* TextStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4478B9BFEC84518FBF6BA118C1E6CB12 /* TextStorage.swift */; }; - 8337E13F01E3FCA88A188BA0D21DFC1E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CEC22C73C1608DFA5D5D78BDCB218219 /* Foundation.framework */; }; - 848F4E74AA194356983ECC45D0B91F61 /* ConstraintMaker.swift in Sources */ = {isa = PBXBuildFile; fileRef = F40232B8523F1EA8697CBB582CA1F105 /* ConstraintMaker.swift */; }; - 8722A0209A541CC726618E59BB5E4067 /* MotionBasic.swift in Sources */ = {isa = PBXBuildFile; fileRef = C38ED1097907390971ADB39EE1414567 /* MotionBasic.swift */; }; - 8926B75526F4140341D9ED25A9BA741B /* ConstraintLayoutGuide+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = A3602387B591F81169705905D0F11DFC /* ConstraintLayoutGuide+Extensions.swift */; }; - 8C8DD9463410992FAD7B9C5D5641AD4A /* ConstraintItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = C109BCAE67952558B9CA8F092EA9A567 /* ConstraintItem.swift */; }; - 8F33FD9490104035547A7050074C539A /* ConstraintInsetTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7CF05888635DDB2556D5E540E1348DE2 /* ConstraintInsetTarget.swift */; }; - 8F84A963BFBD63C6E8D0E05E1E53C9BB /* ConstraintPriorityTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 85315320E60D2D52CC7EAEBBC21463A6 /* ConstraintPriorityTarget.swift */; }; - 90FCFA82AFEAB745E65376964BA7F620 /* Material+Obj-C.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8DC76F38419F33B61224B3BF03F60969 /* Material+Obj-C.swift */; }; - 9245C8B1E62B500F0DCDF3EF8FE7D20B /* EditorController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 49464A1B46F964BB49A6CF2325EC1192 /* EditorController.swift */; }; - 927C84FADB96E6280467637648A1301C /* SearchBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = A7574F5A7DA17DA8433B68FEC4D8E2B4 /* SearchBarController.swift */; }; - 9305975DE58297B119B274A978637993 /* Application.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4E7866B84F0604D70EFAEE508EBB335 /* Application.swift */; }; - 96FDB81A962C446F1FDCCC3598645322 /* SnackbarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C919D01AC4B24B49FC0A9DEE866669D9 /* SnackbarController.swift */; }; - 9796F7CBA480722539E4BAE0074817F6 /* UILayoutSupport+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46E85FD2A85A33D289BA7F89A35422AD /* UILayoutSupport+Extensions.swift */; }; - 9797093A4EEE7DCCC9D6D48FC1898EA9 /* Roboto-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 61CACCAFC625386A3516D06CE236C4BB /* Roboto-Bold.ttf */; }; - 97DCC37E37AC37C980C06F20938E9D58 /* CollectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F8BEA1E432AF10F8BCF4AB7B0D887BA /* CollectionViewController.swift */; }; - 9B60BE7632D171F35D1540E89712E000 /* Material-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 7B07B9C2E705FFD7BBF4A7E5A0183CBE /* Material-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; - 9D1E16ED4552065F8C20B8F370FEF202 /* ConstraintView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5986E6DD7BC1F388CC2A4C4A3E90482C /* ConstraintView+Extensions.swift */; }; - 9D63C1072186D5B5AA06E90DA1B4E92A /* Material+UIView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45870C59B4C74A0325BB8E056C6D37E4 /* Material+UIView.swift */; }; - A4AE628C99F3127A27CA0A169F2F7A43 /* Roboto-Light.ttf in Resources */ = {isa = PBXBuildFile; fileRef = F6EFF83DEE934EA35FEDB304725A8F99 /* Roboto-Light.ttf */; }; - A56A138292D79B686457C4E52E5D50A2 /* ConstraintDSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = CF8F89D38616DD8F9464D1E50D9B6FA2 /* ConstraintDSL.swift */; }; - A5B9441BC6ACB47C57C40FEDBBC777C0 /* SnapKit-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 6922CFF6AB5A3AEB9320BC6491C95F06 /* SnapKit-dummy.m */; }; - A5EE2C2012D918D6AC99A4E89346043D /* Material+CALayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 753507311BD88F21C5B570568F5405D7 /* Material+CALayer.swift */; }; - A73B0852B9086FECBD180497B8442170 /* TableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3D946174F3E557CD4FC1132C6314EF9 /* TableView.swift */; }; - A97198F52DC71E2A2C0FF2074A9A3844 /* ConstraintOffsetTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = A50ABC396DD22F4FFF7DEC63DA7E7C0F /* ConstraintOffsetTarget.swift */; }; - AB209D3AA85A8C3D56C6A3E059606E20 /* ConstraintConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = E69D706A31179C60D704A37D72E084CB /* ConstraintConfig.swift */; }; - AB57F92568F8E8645C122BF5083A92A7 /* Roboto-Thin.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D8083DE096D06A9A9755F0A0620AB65A /* Roboto-Thin.ttf */; }; - AE0D36ED18BD1E056022ED3364665273 /* Menu.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5A40C702BB4A49D472EAA6CFF62F736 /* Menu.swift */; }; - AE18B38EA5587A04AA5AFF5916E8B3F7 /* ConstraintMakerPriortizable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A5E663832EA5319A80F4B865A728BDE /* ConstraintMakerPriortizable.swift */; }; - AF7EBD7DCE6327D16205B22FD19103FF /* TableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A4649840170D6AA34B847908C8F4A7BA /* TableViewCell.swift */; }; - B263CDA6B9D65BC7488E1A9AC0F53389 /* InterimSpace.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C299620A7769FA365FBAABDBE43A589 /* InterimSpace.swift */; }; - BBC23616DAA0BFC1872463EA7FCE8E39 /* Pods-KeyboardSpy_Example-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 60C56E9F90E6D90CF3FD96AFEC2B8699 /* Pods-KeyboardSpy_Example-dummy.m */; }; - BCFD6C12E707FA2385780888B375AC97 /* KeyboardSpy-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 8FD66C72073ECAA2B4FE8D6303DE29D1 /* KeyboardSpy-dummy.m */; }; - C1CF8CF79BD77976B4F10953DF811D79 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C8C4D638529F47D744014C0A1ACFD2B8 /* Assets.xcassets */; }; - C2CBDEA1FF82DB8BA8086FB40D5FFA4D /* Bar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 197255497D2A67D6A76D54E75E642BF7 /* Bar.swift */; }; - C49587EA956AC9B1DB87CCF7448625FA /* Material+String.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D5ECB44A26D6452B990344C6DE6925D /* Material+String.swift */; }; - C520A8827546636A7AE9EE622A20171B /* ConstraintMultiplierTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6CCDA7C0486BEA2F243119352DFAC83 /* ConstraintMultiplierTarget.swift */; }; - C790BFB952FE9D68025179219065B6F7 /* Editor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94FC1BA9ABCA485F6C57ED94897F58A5 /* Editor.swift */; }; - C80AFA937D98F7CFC405F634C5F305EF /* RaisedButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43C21D605ED19DF26BCA60B7A8FA9504 /* RaisedButton.swift */; }; - CAA7BDFA7CFCAD5629BDECF1B739414D /* CollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79F0B45651C9FD2AC25924E3217CA9B5 /* CollectionView.swift */; }; - CC6C627BB67CCED726C16A4DED0D5291 /* MotionPulse.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB03BCD3478615E5CEAF3428ED0E51EE /* MotionPulse.swift */; }; - D0140346362CA3DE42F0A6BED2D33664 /* ConstraintDescription.swift in Sources */ = {isa = PBXBuildFile; fileRef = 76CDE54CBC0B523EFDE97856F05EA6CD /* ConstraintDescription.swift */; }; - D297FDD36FE5963B5EAB5C48D33B5225 /* ConstraintRelatableTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 288B4F9DD6FF27B43CD7529C06ED68DA /* ConstraintRelatableTarget.swift */; }; - D354A63F813200D89CBCDCE13FE5BE5D /* ToolbarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4790179B22BE39130F0A994A92A4F2D /* ToolbarController.swift */; }; - D47CD82DD6BE1BC1356BAB24C63B74E5 /* io.cosmicmind.material.fonts.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 1B67B1C6393B5561FD27F0BACC14C642 /* io.cosmicmind.material.fonts.bundle */; }; - DA23706870F3BCA0BEDD872481AB7457 /* Gravity.swift in Sources */ = {isa = PBXBuildFile; fileRef = F28A4A59DA2F7FBAF40E1ADD8A668F21 /* Gravity.swift */; }; - E12EDE20910982BCECD89DC073B2E144 /* ConstraintView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B08961DD7BA7CD3CED1C08692C90DDA /* ConstraintView.swift */; }; - E288EE18D790F1895E206097030551FF /* NavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 505A33EDE2771A4040D6809A7C7C66A4 /* NavigationController.swift */; }; - E2B2CFCC2D3768220CF9F7335D08B257 /* Border.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7240D4DDCA8892D9B103DD1144E016E9 /* Border.swift */; }; - E31EB4B8B34D52B85629B1C064C9D433 /* Divider.swift in Sources */ = {isa = PBXBuildFile; fileRef = DA6851721F6547D80E863DAFD32DCC41 /* Divider.swift */; }; - E4CA1ACD52102C3397B3301E624B7650 /* CollectionViewLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 278611B3D38290F130D90B40ECB99C02 /* CollectionViewLayout.swift */; }; - E7C3384668CFDBC09EE99EF44BE4D1FB /* ConstraintMakerEditable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 259DD8B4DFDF095A59C643D55C855D5B /* ConstraintMakerEditable.swift */; }; - E7FCE040010DDFCC1C46D70CA417EA1A /* SearchBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9186A695A6BC64DBBD46F73C55B7E9A0 /* SearchBar.swift */; }; - E937898D95469D07EF42711A5B700137 /* Font.swift in Sources */ = {isa = PBXBuildFile; fileRef = C778F6DF76306DC29E9B8555ADDA1D55 /* Font.swift */; }; - EBB704A8ADFB51196A98206041486256 /* Display.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8B7291744862FC3B943875334A37326F /* Display.swift */; }; - EF8EC0245532B6E955344A548E737E51 /* Material+UIImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8B2B6D02B41725C2F09C2C6A2CB90089 /* Material+UIImage.swift */; }; - F0EF73A649E917771D288D49038530A2 /* MenuController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A6AFCED171C156CC0419667D864775C /* MenuController.swift */; }; - F13B12ED9BC99BBC146D594DC60EEAD9 /* ConstraintLayoutSupportDSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = CD409C9F625BE16AA14A0059481BC570 /* ConstraintLayoutSupportDSL.swift */; }; - F4E0B84BC56D3800BF8CFB436090B442 /* BottomNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 612E855F09DF3C6FA7963B1503054960 /* BottomNavigationController.swift */; }; - F55E7BC534A3CD2559EA76F11514BC69 /* NavigationItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21DFF42FFAC4B40307FF15FAC49E2087 /* NavigationItem.swift */; }; - FBBA6EE0DBADFBD0865D9D65EE760D13 /* Material-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 3630DB0B6881F7C6F6F5AB4DBC566B0E /* Material-dummy.m */; }; - FCB163F72D772F3EF6946C6D7D5F7099 /* Motion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 878F505F2614FEFB68522649F4ACA208 /* Motion.swift */; }; - FD234321E262A3B7C19A640D01ADE015 /* DataSourceItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26CD3924B311AABDFC52C4181FF68410 /* DataSourceItem.swift */; }; - FF99F14EBD759D3AE46D76F4CE6EE874 /* CollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8E3D61406E1A615B51C7DDEC3D0226AC /* CollectionViewCell.swift */; }; + 005E87111AB718E3EADDDADD7FF51E0C /* ConstraintConstantTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF8D02890D88B7DD533215654556DF09 /* ConstraintConstantTarget.swift */; }; + 00A36B3D82A970F771B949B095C5AA56 /* PulseView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F66BF21C7F9438187C912CF65A4F61B8 /* PulseView.swift */; }; + 011304F6B7F86A0473E05C896B9A07D6 /* ConstraintMakerPriortizable.swift in Sources */ = {isa = PBXBuildFile; fileRef = A999BD3B694EF67F9145508F09E45B95 /* ConstraintMakerPriortizable.swift */; }; + 01D646C3E8FD950788639235EA734EB6 /* Roboto-Medium.ttf in Resources */ = {isa = PBXBuildFile; fileRef = E56D6440BE5F3B60407251179CAD03A3 /* Roboto-Medium.ttf */; }; + 032F0DC686D2F3DB159B913B3992ACE0 /* ConstraintMakerExtendable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 984BDCC45A221413BAE5828C619531AD /* ConstraintMakerExtendable.swift */; }; + 033C8F83710056A4119206425F8300AA /* KeyboardSpyInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 106445DF942638829B116010BC1317EB /* KeyboardSpyInfo.swift */; }; + 07EBAF3B5177C769228CC46A54758F8E /* com.cosmicmind.material.icons.bundle in Resources */ = {isa = PBXBuildFile; fileRef = C49A43F3F33E4F98D64440EEBA7CAF31 /* com.cosmicmind.material.icons.bundle */; }; + 0A34FFF35DD87698BDCD8CA4EAED377B /* TransitionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 803EC022B8A7FF20442F8462F128CC47 /* TransitionController.swift */; }; + 0A8D5B9C6A790E3B60386D82B053B6FE /* Motion+UIView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B17790D1A558455995AD12F9838E4AFE /* Motion+UIView.swift */; }; + 0B9C7FB837C6824A1A4BAA1DCEDA27ED /* TableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A351C83FF2E10ADA2917C6931D73817 /* TableViewController.swift */; }; + 0BEBBAEABB39A6147908D63B347F8C42 /* Roboto-Light.ttf in Resources */ = {isa = PBXBuildFile; fileRef = D5C87256138351F320508FE53BD4C7BB /* Roboto-Light.ttf */; }; + 0CEBA550622152219CDE78213C3A4450 /* TextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = C61EE6C02AE9902C041D6D8B3D67D533 /* TextField.swift */; }; + 0DC74D0FB022F1EA1EDFBBBFA62A1412 /* NavigationBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5067B551F58C6CBAF02AACA2588B3A2E /* NavigationBar.swift */; }; + 0E35BEAA1C4F8D53B3AC5A5405AA005F /* Switch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1485669703D7EF2F432F23BFFBCF1FF7 /* Switch.swift */; }; + 0EC8AEC224B2F0A586A8D9C4ADCC54CE /* Material+UIViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 916E6656F4A77EDA6ACF9C11736B9520 /* Material+UIViewController.swift */; }; + 18E5ECEF844279891489DAE4FF115124 /* Motion+CG.swift in Sources */ = {isa = PBXBuildFile; fileRef = C7B2A2CEE688E7FBE29FB8C7C6C9C14C /* Motion+CG.swift */; }; + 1A2D832730D6CB1FE7F9EA08DD6CCEDD /* ConstraintView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 162C40AA5CFEF7B409B405C3B381CA5E /* ConstraintView.swift */; }; + 1B2A577EE2C3BC38D98B74B383529776 /* ConstraintOffsetTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55C850B0B5A8873EDC66B9853309D9D9 /* ConstraintOffsetTarget.swift */; }; + 1D61F6D01EE9B908F67B7A275FF254E6 /* ConstraintMakerFinalizable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50C6E544D13AF514C77C14D5637E6FB8 /* ConstraintMakerFinalizable.swift */; }; + 203BF03E16E8F3395C05839B6469FC31 /* ConstraintPriorityTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B1A517903796A6981BAE5E931900276 /* ConstraintPriorityTarget.swift */; }; + 20BF1A4181DEFD602769EC9EB238A123 /* KeyboardSpy-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 13348C98368E04FF1B5010D0FDE1AFDC /* KeyboardSpy-dummy.m */; }; + 212CF544C11552D9B450542D4693E388 /* ToolbarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 16DA0155646F03DCF6DEF433BD7062F2 /* ToolbarController.swift */; }; + 21F51E59AED8D78FC74F1E232F8143AD /* DynamicFontType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F8B3AECB2CE612A01D32F93F28018A0 /* DynamicFontType.swift */; }; + 2230958798AC58DDDB871BAA740824BA /* ConstraintLayoutGuide.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FE148A95C46F92A3BC9823F7A1C2D83 /* ConstraintLayoutGuide.swift */; }; + 228BD9DBB45F0DF8EE5743650D62A1B7 /* ConstraintRelation.swift in Sources */ = {isa = PBXBuildFile; fileRef = CE11A03BFD1F047DF81CE5D8DB7255A7 /* ConstraintRelation.swift */; }; + 233CAD6E0D37779BF56D2C16E07C2A89 /* Material+UIImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15B1DB147338653CC41B55270365A70D /* Material+UIImage.swift */; }; + 25763D4DD43396719BB473D52FB4A800 /* Material+CALayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = A795AFA4EFBE1DC0CDF4312824621FCB /* Material+CALayer.swift */; }; + 27F0539777960A6FFC6CBF9295673211 /* Divider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6F779C0647CC8D560F8253FCC53F4CB7 /* Divider.swift */; }; + 2870E48B34F083B16C2C959BD75FC404 /* CornerRadius.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8AD0C47E4179535B7CA07A252718D02B /* CornerRadius.swift */; }; + 2992AC9140BEDA92B62389EA5B36BD37 /* ConstraintInsets.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82CC1F32060AEA7B22314F7F315C765C /* ConstraintInsets.swift */; }; + 2C977BA53D3D660B16282C57913CF0EF /* IgnoreSubviewModifiersPreprocessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 088E77384B11B6E45BE9A26EAA99DA25 /* IgnoreSubviewModifiersPreprocessor.swift */; }; + 2D0971F0DCF71F5A2FBA6D18F4AF32F8 /* MotionCAAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = E1A932A7AB1D47B56E9F950843DD50C1 /* MotionCAAnimation.swift */; }; + 2E8E0C87F71F29E3130A52EAC8C7E4CC /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6604A7D69453B4569E4E4827FB9155A9 /* Foundation.framework */; }; + 30EB799982F19E3D13B9C8DAAFB2A1BB /* Depth.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A9479DAE0B452979DFBF59758339AE2 /* Depth.swift */; }; + 317A9E558F109B19FE85C84C616FB8AF /* CharacterAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8BFDD5A0A8B86B89D8E34AD0D5E89885 /* CharacterAttribute.swift */; }; + 3283FAC62680D4B28E2F1BF9CD7CFC02 /* FABButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B0B36A7CE96D869B7ACBBB2EBDA905F /* FABButton.swift */; }; + 340810A0CF44A31945F00057467C7AB1 /* TabBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = D27978F3C1B67B34E354A66CA7A4F3E1 /* TabBar.swift */; }; + 3470380DA530E8815FAAF42E763CFDEC /* Toolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 48270BDDE59DE398D04189141411D1AE /* Toolbar.swift */; }; + 349826FE47DC5FAAB50B0CB57B7C2178 /* CollectionReusableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79553E00CC72D70AFF8BB193101579E2 /* CollectionReusableView.swift */; }; + 374552759F369E2F17B795AB2E88638E /* UILayoutSupport+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8B031678B3CB8D481599EACA7794892 /* UILayoutSupport+Extensions.swift */; }; + 38EED7F068EFBF80B0F16D9E52247925 /* Grid.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3D6B71FE7158E9A18B8BC31D2A0C0C3 /* Grid.swift */; }; + 3B8BCA9C6ADEF4201B158DC3A6A04CB6 /* NavigationItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82EB798C1FB4D9EEA1F592220008F4DF /* NavigationItem.swift */; }; + 3E2271B883D9395EAF32726B4AAD33B2 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6604A7D69453B4569E4E4827FB9155A9 /* Foundation.framework */; }; + 3E2306C0DD8E78A5D4F4E1201466FDDA /* Material+String.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9DDA18D5E5704B28AE964CB185FB2F81 /* Material+String.swift */; }; + 3EFEE885BBAF6EAD5D1B2B2DB67EC416 /* MotionCoordinateSpace.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD4A4E8CE120E15B55290A847452C225 /* MotionCoordinateSpace.swift */; }; + 419F139EEF405DD6A546E0A8D623D144 /* RobotoFont.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2814A42589427CEA42ECAFF272BF53C8 /* RobotoFont.swift */; }; + 42267446E84AA4DB7DCBC444B38246EB /* DurationPreprocessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 081A85D61ACC638F8C4609BF0D074707 /* DurationPreprocessor.swift */; }; + 42DB6F9CF427540EC6D8B2C665BF31AC /* Snackbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8223A33C2D47D3C1DBC9D3AB5C7C0CDD /* Snackbar.swift */; }; + 430FDA33C0E2E53D1DEA6395C33CEDAE /* Motion+UIViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E22CD3715683FC8F8421450810107AF5 /* Motion+UIViewController.swift */; }; + 4349F1775A2166C4E17D59BC58158811 /* FlatButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46A628B86F7E8DFD403412AD66BD0DC1 /* FlatButton.swift */; }; + 44DD0A4E583407C658DCEC76C9B9BE64 /* ImageCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A57C4B1BD27B48F524414DBD6A9AC1C /* ImageCard.swift */; }; + 49E8BC64A0A6FF0A908E7A9BE8A12C5A /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 35127700E6E1FD5733A6BB805095905A /* Assets.xcassets */; }; + 4A61E4ED9BE9286A8EDF83FBD6CF1AE8 /* com.cosmicmind.material.fonts.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 89E26B785FD84FC8ED6D7769EC994673 /* com.cosmicmind.material.fonts.bundle */; }; + 4B13ECE4D13EF648F8788A7CEDD6FF06 /* ConstraintInsetTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D28F26EE7BBED72FE444C2E2E378C65 /* ConstraintInsetTarget.swift */; }; + 4CB67C61304D12CF7300825288C75E8F /* Pods-KeyboardSpy_Example-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = EE8F4318B6998AD8B763D75C3C2779DD /* Pods-KeyboardSpy_Example-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 4D6AB54D0B5BD084A267F46A5CA694C3 /* ChipBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3B704A01CFF273B6E6817C31A201649 /* ChipBar.swift */; }; + 5083A2E487712FED80A714BCA40691F5 /* MotionViewPropertyViewContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 032BE899369FCD6BA85FD0ACC035AF01 /* MotionViewPropertyViewContext.swift */; }; + 52E5917269886C8174E68FB4DC2B47F0 /* MotionHasInsertOrder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8BE935A6FC3B6BDA73FC5D76069040CB /* MotionHasInsertOrder.swift */; }; + 5475AA1F4BCEEC69D4A160C970E4940B /* SearchBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B962828A6BE66FBF013FB6CBC6C0376 /* SearchBarController.swift */; }; + 5787FE13473CA22BF235F75AECD773EB /* IconButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF349907A54AB4AB35912BB4297D237 /* IconButton.swift */; }; + 5986374897FB6600354E426C637F11DD /* ConstraintLayoutSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6FE94E6DE0E4563E476761744B199D4F /* ConstraintLayoutSupport.swift */; }; + 59F3195723100D08A25D37E169C26D98 /* CollectionViewLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3D81F6D5952A9F3A463C70D2BCF43E73 /* CollectionViewLayout.swift */; }; + 5D072CAC30B46DFE2BE3448C5937E490 /* CollectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 60259A0DAF13057DAC54F362932F7E52 /* CollectionViewController.swift */; }; + 5DCDF6F753EFF0C71839E275D82BD246 /* Motion+Obj-C.swift in Sources */ = {isa = PBXBuildFile; fileRef = DF1EDDBFF8C329BD4F24163606F15863 /* Motion+Obj-C.swift */; }; + 5DCFA206F133DA1443C76380B6523229 /* MotionAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 499408A4B19535EBD30AEA2EF4FB99C5 /* MotionAnimation.swift */; }; + 5E426DB8406EF0CA404F2FC29A79F8E9 /* SourcePreprocessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 248A4B01BB125D3E899952287A81ABAE /* SourcePreprocessor.swift */; }; + 60F9587E2995FCBD2D9E4F7D96518547 /* Font.swift in Sources */ = {isa = PBXBuildFile; fileRef = 063C827D23F6C30673679EF4962B80BA /* Font.swift */; }; + 618F2B4864EF2094F213F69D23CAFC86 /* MotionAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = A240F13043E832ED2C0DE4197F53986C /* MotionAnimator.swift */; }; + 631F2D66F64E306AEB2040F3CC4EECC3 /* PulseAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66AA832FAEC662DFE2E79B120597DB97 /* PulseAnimation.swift */; }; + 66AF531C017FC9C06138060F169F69E0 /* Roboto-Thin.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 59FD8B4965A0D2142072455B539D3A3B /* Roboto-Thin.ttf */; }; + 6775E0A854154AEC0F7F4B264BAB95EB /* Color.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66BAB4D25B723308397559B82DC7B545 /* Color.swift */; }; + 682DBA88A140AA358F42615D531809E8 /* Roboto-Bold.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 12D24C71A37F797ED7281CFE66DEB8ED /* Roboto-Bold.ttf */; }; + 69825A74C86113E8BFFFDD990A1B4483 /* ConstraintLayoutGuideDSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = E3E8770F8014FD52A4063DDCBF99F3AF /* ConstraintLayoutGuideDSL.swift */; }; + 6988699AE65690D9A0F37F9AD7D9129C /* Screen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 820338254434C6CB3C9C9ECC0D575906 /* Screen.swift */; }; + 6BAFDE4F917DA65F7A7CEDBA8FDB11A4 /* ConstraintView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD1440E42271BB98ED919BE226C8C8A7 /* ConstraintView+Extensions.swift */; }; + 6C37A2568A764B378F940094FAF64BAE /* ConstraintLayoutSupportDSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8655037FB101023F644AB93D46531E3B /* ConstraintLayoutSupportDSL.swift */; }; + 6CB63AB35EDD699D46456ACE62D3BA2E /* RaisedButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5A42AE8FC34C0BFCEB2CC540BF41F869 /* RaisedButton.swift */; }; + 6D5715694A543CDC054984C92FD230F1 /* MotionContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B6003FCCEBCB8E473887B41D4DCB25B /* MotionContext.swift */; }; + 6DE54531EA11A594E853A02F28521680 /* SnapKit-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 4693FC54E08F8CC0F4649066F0000071 /* SnapKit-dummy.m */; }; + 6F2DFA6333E6DA36AC571A475B167C56 /* Border.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A8B9E37554D126D24D44B9611A779F2 /* Border.swift */; }; + 71E255C4A6F65EA8965346B4F71C9C2E /* Device.swift in Sources */ = {isa = PBXBuildFile; fileRef = A6663232B21A072859EDE9347DEA9C07 /* Device.swift */; }; + 72AA010724B4D03C95DE306EEA951F58 /* Material+MotionAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB04C0C99C8D6CF1DE9805D6EB74578D /* Material+MotionAnimation.swift */; }; + 72D1B052A4977B4D3D21544EFA65423D /* MotionTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = F33DF18C8CC85F9333323B05E2BCFDBC /* MotionTransition.swift */; }; + 7605F9C36D2E99FBD8EC41B93F13AC2E /* Layer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91356D8E95C500958415574ED91CF53C /* Layer.swift */; }; + 76F4139461A827C32772CB47A2032B75 /* Pods-KeyboardSpy_Example-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 60C56E9F90E6D90CF3FD96AFEC2B8699 /* Pods-KeyboardSpy_Example-dummy.m */; }; + 77B1926F11AC1B1249D03D61B9BA05DB /* SnapKit-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 2CE1FF341717F3DC7D7B063D6B0A0A86 /* SnapKit-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 78B44D65414EE139DDF167A2B0A00365 /* FABMenu.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4FE4756F341027C2CA36BFB29AD3FED /* FABMenu.swift */; }; + 7A2DC0502FE0A40266D6DCA2850A1EE1 /* FABMenuController.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF064103CED8717386EE459CA9A3FBFB /* FABMenuController.swift */; }; + 7BA206A0830E9E19358856A7C0B762E2 /* ErrorTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 997E15A2B422B6F94889B04D865E0D1D /* ErrorTextField.swift */; }; + 7D7E11AD1344976DB0D9DD68DB3C4058 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6604A7D69453B4569E4E4827FB9155A9 /* Foundation.framework */; }; + 7E388B5E14B39321B06A6E9CCDED0AE4 /* NavigationDrawerController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9E33F9931AA03B2C728FF889D2CA2835 /* NavigationDrawerController.swift */; }; + 7EFE33398572E74E2C571216EFEC61A2 /* Material+UIWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53693D841B2B8BCD50FC5A5EB1A7C254 /* Material+UIWindow.swift */; }; + 80AEAE02F3E1B75151CD5CB9FA66BE8A /* TableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2ACB20CA2B272DAC4B439935F1759B2E /* TableView.swift */; }; + 829484505F896CEA0E759C6613FCBEE3 /* CollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FE42BE25C4F00855A05A62C8BE5AF0A3 /* CollectionView.swift */; }; + 83346C7329B66DC89DD08399BB402822 /* MotionSnapshotType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 338FE444D8BAFEBC0759FD9F96748DC7 /* MotionSnapshotType.swift */; }; + 8428A9EA4C7D682AB7F80CCD36BED3BA /* TableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8B21646206535ACA03016E06B41E7D2B /* TableViewCell.swift */; }; + 8583A7495E2057773C740E07C62F50D3 /* ConstraintMaker.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5FC610D3C48E59F922BB216202B7B42 /* ConstraintMaker.swift */; }; + 863459EDE07FABCB88A17DD90FE122F2 /* ConstraintLayoutGuide+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B7223A3519C06913B81B56CB2A3A39D /* ConstraintLayoutGuide+Extensions.swift */; }; + 8B4FDB372E2E397AB249F66454F5040C /* Constraint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3CA3D8AF992D96CE94963FF1839EEBFB /* Constraint.swift */; }; + 8FFB51B8411191E2B387524032776803 /* Application.swift in Sources */ = {isa = PBXBuildFile; fileRef = EFE796CA3ECFC814DDF9D7EB147F9924 /* Application.swift */; }; + 971992D40047BD9904BFD2C2594D2AE3 /* ConstraintMakerEditable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB89BE5CF96047F5BB17B37983B6D44F /* ConstraintMakerEditable.swift */; }; + 97AF3F674B6F7E81980C8BB0968283FD /* MotionController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC2A7794E9A8E4BF593E8BEA3CC13F9A /* MotionController.swift */; }; + 98947C919BFCC23F72CEFC99254384B3 /* Material+UIFont.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E09CD729CD53ECADE86C5CAA46AFEA2 /* Material+UIFont.swift */; }; + 98EEFDF381873F6F122D7F6D2072B840 /* DataSourceItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = C0833A6504E0C528A274EE2E3695DE5B /* DataSourceItem.swift */; }; + 9ADB674635B12AE658E36BC199D96666 /* ConstraintDescription.swift in Sources */ = {isa = PBXBuildFile; fileRef = C54DC92432F36790BD880DD997A13397 /* ConstraintDescription.swift */; }; + 9B899B1FDFFAD41CCD315ABA89E96169 /* MotionPreprocessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0160981436DACD22BEAB0879E24620A7 /* MotionPreprocessor.swift */; }; + 9D33D752F8F1D789262767240753046A /* HeightPreset.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D67D847A76445CFABB19330480C5729 /* HeightPreset.swift */; }; + 9DC23DC52665A9ECE2E7CAA4B8E5AB03 /* CardCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = A98FA3A05CCC692F52ADFBC6D639731F /* CardCollectionViewCell.swift */; }; + 9E8303279366A81AB681258A0F8A2DD5 /* ConstraintPriority.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7CE5C53A344F86A38A3791DFD39984A0 /* ConstraintPriority.swift */; }; + 9EC473D1895C30979CF1C5C92ADE0C46 /* Offset.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2EC919E0280AFAFAB77B12431195872 /* Offset.swift */; }; + 9F46AEDFD7CC94A04723B5F2CB5614EA /* KeyboardSpyAgent.swift in Sources */ = {isa = PBXBuildFile; fileRef = EDDDE5E1B478A07CA02F3DDFEB4E2B2E /* KeyboardSpyAgent.swift */; }; + A3B24C60F178A193C64F96D216E04A5A /* SearchBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 27105484605742DDCC8DE41C54728AE7 /* SearchBar.swift */; }; + A760C777574AB7762F4395432369B080 /* Material+Array.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96C22AFB26EE0F5060AC4A1773505C2A /* Material+Array.swift */; }; + A8D63483ABE5D98359765BAB2CB0CB6E /* Card.swift in Sources */ = {isa = PBXBuildFile; fileRef = 789F24D8EB68E2D2479D47439BF3FFA1 /* Card.swift */; }; + A974074BAACE59E199D98A7E6A0D309D /* ConstraintRelatableTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C611A36A6E9F1AC68597DA589384EFD /* ConstraintRelatableTarget.swift */; }; + AB997A4BD3241FC9C29A3567F85C8DB9 /* TextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 62AA6DA8DD31877CCBED3B41BAE939C3 /* TextView.swift */; }; + ABB1D6F06BCCF17E8BC732BC0811ACD4 /* CollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D3A35CC89BE0B3799F6CC1D2AD20AEC3 /* CollectionViewCell.swift */; }; + ACF7533531EB81FB89FB8A1E2D9743FE /* ConstraintItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D080E614C5165DFBED6BFAACECE1CCB /* ConstraintItem.swift */; }; + ADB27961B4F26F93C16FA889A96DA792 /* ConstraintViewDSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = AEC428ECD599B5F5E5D6366D3D812BE8 /* ConstraintViewDSL.swift */; }; + AF14FC0BEA2138DB66723C317301A27D /* NavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 341D52075E4B522176783D1F09D77CBB /* NavigationController.swift */; }; + B02DAF3AC652A417CC799301CAFF0027 /* Roboto-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 59FD9FB5A3AD6E1E2456A1E9B770AD18 /* Roboto-Regular.ttf */; }; + B2209FF6A03930DDE4171C07FBFE26F6 /* ChipBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4A081494ECAF4DF9F69FD642B5E83605 /* ChipBarController.swift */; }; + B686052BEEA72CEDED17B0B0D321D5EA /* SnackbarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 744F73221AAB025C438C3CD405A68D67 /* SnackbarController.swift */; }; + B6F789A90051F2F7A0B8E977C9219AD8 /* View.swift in Sources */ = {isa = PBXBuildFile; fileRef = 562520D21C313BC739ADA36597DE7B37 /* View.swift */; }; + B943391BE943BE0F0AACC18D84748275 /* InterimSpace.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9FBDADDBB78E63A6F8F536C1A8A1BF6C /* InterimSpace.swift */; }; + BA98FC1793725CE258FDE198B3EF3B7B /* Debugging.swift in Sources */ = {isa = PBXBuildFile; fileRef = EB02DAC86275C42724DEAE2F9FE4E176 /* Debugging.swift */; }; + BAF3320D8CEE07BAF7D6F7DE561214E1 /* EdgeInsets.swift in Sources */ = {isa = PBXBuildFile; fileRef = EFD6D0315D42263212698DD1E325BC26 /* EdgeInsets.swift */; }; + BCCDA4E282F640D8F1B027116C795157 /* ConstraintDSL.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15FD1EFE0D3328228965408D9F9FDE04 /* ConstraintDSL.swift */; }; + C0D3D3CCC50F9EBCD10BF38B0C9B8A6B /* MotionAnimationState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 487A400166FA22AD3E9B612510E7B7F1 /* MotionAnimationState.swift */; }; + C3DA93801BE0BBC0152DD7CDB453B22A /* Motion+Array.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F88EF8CD7E5ECCD9A2AE3D934B4B2A1 /* Motion+Array.swift */; }; + C549768BABBED1C32593ADDF2AB24272 /* KeyboardSpy.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE4266C158269835E765361130F0558A /* KeyboardSpy.swift */; }; + C721A5E19F7B107EF497F74A9A675D56 /* Bar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03412EF3A7A9D5489314B7F6FAF17EB4 /* Bar.swift */; }; + C8B332AAC8BF202036A7123E69F715BF /* Icon.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A4303A2BEA3726D0E5E09F049E7353E /* Icon.swift */; }; + C9890F1484C54D5B0796FA51F968B48E /* Motion+CAMediaTimingFunction.swift in Sources */ = {isa = PBXBuildFile; fileRef = C82088279A7BAC2ACA71BD231A794B45 /* Motion+CAMediaTimingFunction.swift */; }; + CF48B55B39379054482C3EC80E0EEB72 /* ConstraintMakerRelatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 898E73CD666E0111686A18C887582A52 /* ConstraintMakerRelatable.swift */; }; + D31FECBF3A17A0A6857B29A5B74DB2B0 /* SpringAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D574C53286086E5ADCBC3B2172BB541D /* SpringAnimation.swift */; }; + D456FA51D80D980FCD917E93FF9CF563 /* BottomNavigationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CF77ADF624A2A645718F20F388FF409 /* BottomNavigationController.swift */; }; + D4F0037004B942FAD150FEF023EE357F /* CascadePreprocessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 724F8483EBF2FD26F4D41D63F64B2220 /* CascadePreprocessor.swift */; }; + D5084D8FD090947A72843A62721868C4 /* Typealiases.swift in Sources */ = {isa = PBXBuildFile; fileRef = 217562B7ED2569ADDAAA68BFDA380FC4 /* Typealiases.swift */; }; + D519BF78DAD9D88A36801B6F8199D225 /* MotionCoreAnimationViewContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90914AE4D3F87A0BDB6083372A492EDF /* MotionCoreAnimationViewContext.swift */; }; + D6DCF082035B59E817006A1898B07A27 /* Motion+CALayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = B79769A1E065BEE70DED915FB67360BA /* Motion+CALayer.swift */; }; + D982501E51CD6C09A377EF0173DAD361 /* TextStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43DA5D78DA585F03E7335F023388071C /* TextStorage.swift */; }; + D98ADB2D5F898C7FC70747212BF98DF0 /* MotionAnimationFillMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74CF9573521287109B626947CE07DFF4 /* MotionAnimationFillMode.swift */; }; + D99CDFFF1F63572EBE2D687E3737C25B /* MotionAnimatorViewContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 333EC9315BA04B42207F035F62305FEB /* MotionAnimatorViewContext.swift */; }; + DA9A81098A23094833F7B6712566AC5C /* MotionIndependentController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E6BD2E15F44CC91A2451ACC85A5CF9A /* MotionIndependentController.swift */; }; + DB0ECB9132998626B268DEAACACF42DA /* MotionTransitionObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB514EB93F1D1F059B49B8382FEBD7EF /* MotionTransitionObserver.swift */; }; + DFD66F5101BFE82712C43DE9F607C659 /* Shape.swift in Sources */ = {isa = PBXBuildFile; fileRef = F147E88F444EB0CC44F735B0844EC33F /* Shape.swift */; }; + DFD93DEA5204068949EC80286A95E3FC /* TransitionPreprocessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = A49A02172E372515A37DFB2B609B718F /* TransitionPreprocessor.swift */; }; + E17C9E65E4105A57A08030B32154AB13 /* Material-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 0070AC44FD24B99EE52892DF1AD1F220 /* Material-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E1A3E75068301E782D51D0ACCAFAE851 /* StatusBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B407895836E5055B827DDF5582B2F5E /* StatusBarController.swift */; }; + E2255C1CF40161E107499A05C05E4535 /* KeyboardSpy-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 746C113ED7D893C564FB2212795C20A9 /* KeyboardSpy-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E41D9398364755B9A7B25920F9BB5116 /* MotionTransitionState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1A3C0F320BA6193469A5EA85A4506036 /* MotionTransitionState.swift */; }; + E575C81FA77C27D00412B7B6A099FE33 /* ConstraintConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C223604E639DF5ADA18E089ECE32979 /* ConstraintConfig.swift */; }; + E6923B5D55C1AC8D8A8AC198D8932759 /* MatchPreprocessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBAC8A27D3958D51129ADE237A6BB871 /* MatchPreprocessor.swift */; }; + E6F376E7F49EF10B10A066B6F4E4F722 /* TabsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7738D28DAE703698826FF9FC7C9AB092 /* TabsController.swift */; }; + E996062345CFA8AA6CE4C411DD56C535 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6604A7D69453B4569E4E4827FB9155A9 /* Foundation.framework */; }; + ECF0BA2807CDCB6295DE031A4E24BF3B /* DisplayStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = CFFD8A5A2C59A73F737A1845C022FA12 /* DisplayStyle.swift */; }; + EDAB5E7454C3C2EC5E9C7E4C7EDDE3D8 /* LayoutConstraintItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = E82E40F4B23B27C90916581A7B4092DF /* LayoutConstraintItem.swift */; }; + F0D5947F7BD5A430811FE042A1B68193 /* MotionPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C6FCC5CDB1D913BD264CDB67C86F4F4 /* MotionPlugin.swift */; }; + F298FF46E6C6B996C833F3CE6BEBFB2A /* MotionTransitionAnimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7C8884F6E1A3577084D069711AFA8A3D /* MotionTransitionAnimator.swift */; }; + F3714079FE1F8010C452157B4E330364 /* Button.swift in Sources */ = {isa = PBXBuildFile; fileRef = 802641A5CF1A76C57D3BB9B8ACFC012F /* Button.swift */; }; + F3B72D5CF31DC5B25096C569FA9535F6 /* Motion+UIKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 36B37F159DFEF0BE9004762ECB656187 /* Motion+UIKit.swift */; }; + F4321205AF2D78E63456231202EE3DDA /* Motion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58C29E8BB6FFFBF28CD92D380CAE0968 /* Motion.swift */; }; + F56133A1A940BCBB47502861EFAE7DC4 /* ConstraintAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 96D9601403ED520105BF0F34E0F63125 /* ConstraintAttributes.swift */; }; + F63725D70FFAEDA45E74FCFA16DCCD2E /* LayoutConstraint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 17264F50AD3297E8101D3773EA1CDD10 /* LayoutConstraint.swift */; }; + F66051524782B05A34F39EE51E290468 /* PresenterCard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A5E3544BD773E033215450E9F0FBFD5 /* PresenterCard.swift */; }; + F6B20D0B4582D2160277122EC163BFA4 /* Layout.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1D14CD0FA0EA6589A755F5E831231F9 /* Layout.swift */; }; + F6C7244470E241EDE3B63FF86C13F807 /* KeyboardSpyEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56A6EDBCEF4058D3E0479D91F7557D74 /* KeyboardSpyEvent.swift */; }; + F87C7079ABD93A491569C22E28EA550B /* CardCollectionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 950728AD99C523FE9AC4AF021A912D98 /* CardCollectionViewController.swift */; }; + F8B666DB156DA86ADACC879FF0A141B2 /* Material-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = F1C686E4EAE28D0BE02E823A6B18FB81 /* Material-dummy.m */; }; + FA57F7B06160B7831AF602F195228F65 /* Material+UIView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D012601CD0E44779C7B38BACB100B084 /* Material+UIView.swift */; }; + FBCD752E37B53A1F0C028EDC25841E12 /* ConstraintMultiplierTarget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C1C187FD8952ED399F7B5EC47D4AA9C /* ConstraintMultiplierTarget.swift */; }; + FC8392B60F1FC8DDAB3719C1FDFE424E /* Gravity.swift in Sources */ = {isa = PBXBuildFile; fileRef = C807F9DBF420871936843B8A0FC1736E /* Gravity.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ - 0B5A6F5E5F10490C703C97509E627E99 /* PBXContainerItemProxy */ = { + 03ED6BFE2BFDFDCA0C6A4CFF8F0FA467 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; proxyType = 1; - remoteGlobalIDString = 4A3AED5BAF9E9AF799FE28CFB72FE3F7; - remoteInfo = "Material-io.cosmicmind.material.fonts"; + remoteGlobalIDString = 415640AE1BAB89361F9D757D666EB139; + remoteInfo = Material; }; - 60210F77EA66C0C8280299D57726D095 /* PBXContainerItemProxy */ = { + 391E40A3270DC79E4109B71526FB8311 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; proxyType = 1; - remoteGlobalIDString = 36D7B55B95E6A1236AEF513E8FD9238E; - remoteInfo = KeyboardSpy; + remoteGlobalIDString = 4CBC8DD3CD3F13C4EF87425DF5B8AC9A; + remoteInfo = "Material-com.cosmicmind.material.icons"; }; - 761E989276C2C0D088BC262BDAE666CD /* PBXContainerItemProxy */ = { + 3CF9B67E3D8F9FE4A4A3546D323744E5 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; proxyType = 1; - remoteGlobalIDString = 0FB771E0DE35ABAFDF00C9CA54493BDD; - remoteInfo = Material; + remoteGlobalIDString = 8303ECB6B90CFF1D24DA6ADA7CAFD334; + remoteInfo = KeyboardSpy; }; - 7A61A66BCC069B9EDB985046BEA0D122 /* PBXContainerItemProxy */ = { + 4AE3FE1948E04A0CDC1E7F1E24475F4D /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; proxyType = 1; - remoteGlobalIDString = EE23AC8CFA049B54594921CED4E38996; - remoteInfo = "Material-io.cosmicmind.material.icons"; + remoteGlobalIDString = 9A7B3FB64E7B250083D638DAA82A1180; + remoteInfo = SnapKit; }; - C54D1C6BA7F3CAD8CC67CC9AFD3ABACF /* PBXContainerItemProxy */ = { + F6C7521CE7F1019BF4FC0FE999137331 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; proxyType = 1; - remoteGlobalIDString = E6EDA33F2979D1FBE905B02DD311590D; - remoteInfo = SnapKit; + remoteGlobalIDString = 2D6B45908ECC3888F51EC4CF7298F759; + remoteInfo = "Material-com.cosmicmind.material.fonts"; }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 01E281BC27F0ADF6A78211E32A61BE7F /* PulseView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PulseView.swift; path = Sources/iOS/PulseView.swift; sourceTree = ""; }; - 04F5D2F7D208372B8E2D22C1AEEA8424 /* Material+UIFont.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Material+UIFont.swift"; path = "Sources/iOS/Material+UIFont.swift"; sourceTree = ""; }; - 058D958E907406F5AA26CAF6CF734232 /* CollectionReusableView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CollectionReusableView.swift; path = Sources/iOS/CollectionReusableView.swift; sourceTree = ""; }; + 0070AC44FD24B99EE52892DF1AD1F220 /* Material-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Material-umbrella.h"; sourceTree = ""; }; + 0160981436DACD22BEAB0879E24620A7 /* MotionPreprocessor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MotionPreprocessor.swift; path = Sources/Frameworks/Motion/Sources/Preprocessors/MotionPreprocessor.swift; sourceTree = ""; }; + 018E7026FF729DB32184167466D959AF /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 032BE899369FCD6BA85FD0ACC035AF01 /* MotionViewPropertyViewContext.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MotionViewPropertyViewContext.swift; path = Sources/Frameworks/Motion/Sources/Animator/MotionViewPropertyViewContext.swift; sourceTree = ""; }; + 03412EF3A7A9D5489314B7F6FAF17EB4 /* Bar.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Bar.swift; path = Sources/iOS/Bar.swift; sourceTree = ""; }; 05B9FB8DAADA38B14AB68493C55221B9 /* Pods-KeyboardSpy_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-KeyboardSpy_Example.release.xcconfig"; sourceTree = ""; }; - 060FB1C443967E5FB108D964A3315244 /* PresenterCard.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PresenterCard.swift; path = Sources/iOS/PresenterCard.swift; sourceTree = ""; }; - 0F3D602E6FBCE343A9F449D13208571B /* ConstraintViewDSL.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintViewDSL.swift; path = Source/ConstraintViewDSL.swift; sourceTree = ""; }; - 0F8BEA1E432AF10F8BCF4AB7B0D887BA /* CollectionViewController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CollectionViewController.swift; path = Sources/iOS/CollectionViewController.swift; sourceTree = ""; }; - 10440FE2C155F716F5B22EAF2558CFD2 /* ConstraintLayoutSupport.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintLayoutSupport.swift; path = Source/ConstraintLayoutSupport.swift; sourceTree = ""; }; - 11210AFBDE6150A11B9352BE81DB9B59 /* Card.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Card.swift; path = Sources/iOS/Card.swift; sourceTree = ""; }; - 137CA1F1B10E4EC527FD79DA09B9A232 /* Roboto-Medium.ttf */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = file; name = "Roboto-Medium.ttf"; path = "Sources/Font/Roboto/Roboto-Medium.ttf"; sourceTree = ""; }; - 1508FE4D19F51D57ABD80E4E5DA55A6E /* ConstraintLayoutGuide.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintLayoutGuide.swift; path = Source/ConstraintLayoutGuide.swift; sourceTree = ""; }; - 18629F95148CC79833990FCD8C931D46 /* SnapKit.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = SnapKit.modulemap; sourceTree = ""; }; - 188202353462A51F258C407A71543BDF /* NavigationBar.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NavigationBar.swift; path = Sources/iOS/NavigationBar.swift; sourceTree = ""; }; - 18E13B7190D852B4061B2763D342560E /* ConstraintInsets.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintInsets.swift; path = Source/ConstraintInsets.swift; sourceTree = ""; }; - 197255497D2A67D6A76D54E75E642BF7 /* Bar.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Bar.swift; path = Sources/iOS/Bar.swift; sourceTree = ""; }; - 1AA631E65680AB84D04DA6E325AC5149 /* PageTabBarController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PageTabBarController.swift; path = Sources/iOS/PageTabBarController.swift; sourceTree = ""; }; - 1AB532552FB417CAD645F0C6B302AFA3 /* BottomTabBar.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BottomTabBar.swift; path = Sources/iOS/BottomTabBar.swift; sourceTree = ""; }; - 1B08961DD7BA7CD3CED1C08692C90DDA /* ConstraintView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintView.swift; path = Source/ConstraintView.swift; sourceTree = ""; }; - 1B67B1C6393B5561FD27F0BACC14C642 /* io.cosmicmind.material.fonts.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = io.cosmicmind.material.fonts.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; - 1B68143D947DEF19A7E8AA56B37B7CF9 /* KeyboardSpyInfo.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = KeyboardSpyInfo.swift; sourceTree = ""; }; - 21DFF42FFAC4B40307FF15FAC49E2087 /* NavigationItem.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NavigationItem.swift; path = Sources/iOS/NavigationItem.swift; sourceTree = ""; }; - 22FF2B67C144E96CBCDA8E4B0DBBFB60 /* FabButton.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FabButton.swift; path = Sources/iOS/FabButton.swift; sourceTree = ""; }; - 2358315198A7C0E84C8A34438C6360D5 /* SnapKit.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SnapKit.xcconfig; sourceTree = ""; }; - 238367CB9EE1D75CA44120096771C5FC /* TextView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TextView.swift; path = Sources/iOS/TextView.swift; sourceTree = ""; }; - 23C6DA2BCB6964F446E9085159C902AB /* CornerRadius.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CornerRadius.swift; path = Sources/iOS/CornerRadius.swift; sourceTree = ""; }; - 259DD8B4DFDF095A59C643D55C855D5B /* ConstraintMakerEditable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintMakerEditable.swift; path = Source/ConstraintMakerEditable.swift; sourceTree = ""; }; - 26CD3924B311AABDFC52C4181FF68410 /* DataSourceItem.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DataSourceItem.swift; path = Sources/iOS/DataSourceItem.swift; sourceTree = ""; }; - 278611B3D38290F130D90B40ECB99C02 /* CollectionViewLayout.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CollectionViewLayout.swift; path = Sources/iOS/CollectionViewLayout.swift; sourceTree = ""; }; - 279BD983E3CB70058E72691E62FAB246 /* ConstraintMakerRelatable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintMakerRelatable.swift; path = Source/ConstraintMakerRelatable.swift; sourceTree = ""; }; - 288B4F9DD6FF27B43CD7529C06ED68DA /* ConstraintRelatableTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintRelatableTarget.swift; path = Source/ConstraintRelatableTarget.swift; sourceTree = ""; }; + 063C827D23F6C30673679EF4962B80BA /* Font.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Font.swift; path = Sources/iOS/Font.swift; sourceTree = ""; }; + 081A85D61ACC638F8C4609BF0D074707 /* DurationPreprocessor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DurationPreprocessor.swift; path = Sources/Frameworks/Motion/Sources/Preprocessors/DurationPreprocessor.swift; sourceTree = ""; }; + 088E77384B11B6E45BE9A26EAA99DA25 /* IgnoreSubviewModifiersPreprocessor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IgnoreSubviewModifiersPreprocessor.swift; path = Sources/Frameworks/Motion/Sources/Preprocessors/IgnoreSubviewModifiersPreprocessor.swift; sourceTree = ""; }; + 0C223604E639DF5ADA18E089ECE32979 /* ConstraintConfig.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintConfig.swift; path = Source/ConstraintConfig.swift; sourceTree = ""; }; + 0D28F26EE7BBED72FE444C2E2E378C65 /* ConstraintInsetTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintInsetTarget.swift; path = Source/ConstraintInsetTarget.swift; sourceTree = ""; }; + 106445DF942638829B116010BC1317EB /* KeyboardSpyInfo.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KeyboardSpyInfo.swift; path = KeyboardSpy/Classes/KeyboardSpyInfo.swift; sourceTree = ""; }; + 10A0D7EA5610BE39E9FB3DCF7850EA46 /* Material.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = Material.modulemap; sourceTree = ""; }; + 12D24C71A37F797ED7281CFE66DEB8ED /* Roboto-Bold.ttf */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = file; name = "Roboto-Bold.ttf"; path = "Sources/Font/Roboto/Roboto-Bold.ttf"; sourceTree = ""; }; + 13348C98368E04FF1B5010D0FDE1AFDC /* KeyboardSpy-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "KeyboardSpy-dummy.m"; sourceTree = ""; }; + 1485669703D7EF2F432F23BFFBCF1FF7 /* Switch.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Switch.swift; path = Sources/iOS/Switch.swift; sourceTree = ""; }; + 15B1DB147338653CC41B55270365A70D /* Material+UIImage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Material+UIImage.swift"; path = "Sources/iOS/Material+UIImage.swift"; sourceTree = ""; }; + 15FD1EFE0D3328228965408D9F9FDE04 /* ConstraintDSL.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintDSL.swift; path = Source/ConstraintDSL.swift; sourceTree = ""; }; + 162C40AA5CFEF7B409B405C3B381CA5E /* ConstraintView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintView.swift; path = Source/ConstraintView.swift; sourceTree = ""; }; + 16DA0155646F03DCF6DEF433BD7062F2 /* ToolbarController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ToolbarController.swift; path = Sources/iOS/ToolbarController.swift; sourceTree = ""; }; + 17264F50AD3297E8101D3773EA1CDD10 /* LayoutConstraint.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = LayoutConstraint.swift; path = Source/LayoutConstraint.swift; sourceTree = ""; }; + 1A351C83FF2E10ADA2917C6931D73817 /* TableViewController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TableViewController.swift; path = Sources/iOS/TableViewController.swift; sourceTree = ""; }; + 1A3C0F320BA6193469A5EA85A4506036 /* MotionTransitionState.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MotionTransitionState.swift; path = Sources/Frameworks/Motion/Sources/MotionTransitionState.swift; sourceTree = ""; }; + 1A8B9E37554D126D24D44B9611A779F2 /* Border.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Border.swift; path = Sources/iOS/Border.swift; sourceTree = ""; }; + 217562B7ED2569ADDAAA68BFDA380FC4 /* Typealiases.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Typealiases.swift; path = Source/Typealiases.swift; sourceTree = ""; }; + 248A4B01BB125D3E899952287A81ABAE /* SourcePreprocessor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SourcePreprocessor.swift; path = Sources/Frameworks/Motion/Sources/Preprocessors/SourcePreprocessor.swift; sourceTree = ""; }; + 27105484605742DDCC8DE41C54728AE7 /* SearchBar.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SearchBar.swift; path = Sources/iOS/SearchBar.swift; sourceTree = ""; }; + 2814A42589427CEA42ECAFF272BF53C8 /* RobotoFont.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RobotoFont.swift; path = Sources/iOS/RobotoFont.swift; sourceTree = ""; }; + 2ACB20CA2B272DAC4B439935F1759B2E /* TableView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TableView.swift; path = Sources/iOS/TableView.swift; sourceTree = ""; }; 2C32891C58F0EE71E47F861131B5430A /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 2EA88863FE5C899F0B300BB6271371DE /* Screen.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Screen.swift; path = Sources/iOS/Screen.swift; sourceTree = ""; }; - 308A0B595DF71E47E4D305564E1639E3 /* LayoutConstraint.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = LayoutConstraint.swift; path = Source/LayoutConstraint.swift; sourceTree = ""; }; - 32674C09DDF5A4B00A014DB05099CBB6 /* Material.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Material.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 35816A481311F72E21C7D87A865527A3 /* MotionTransition.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MotionTransition.swift; path = Sources/iOS/MotionTransition.swift; sourceTree = ""; }; - 3630DB0B6881F7C6F6F5AB4DBC566B0E /* Material-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Material-dummy.m"; sourceTree = ""; }; - 39CA1D743E25A38354A5D1C016E73BBC /* Material+UIWindow.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Material+UIWindow.swift"; path = "Sources/iOS/Material+UIWindow.swift"; sourceTree = ""; }; - 3A5E663832EA5319A80F4B865A728BDE /* ConstraintMakerPriortizable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintMakerPriortizable.swift; path = Source/ConstraintMakerPriortizable.swift; sourceTree = ""; }; - 3BD648A25F73C4812338D3CC67A16113 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 3E3F318769C538096A7AF92767CD5E67 /* ErrorTextField.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ErrorTextField.swift; path = Sources/iOS/ErrorTextField.swift; sourceTree = ""; }; - 3EA7E84D555B4C827992F84B7CE5F2CD /* KeyboardSpy.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = KeyboardSpy.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 43C21D605ED19DF26BCA60B7A8FA9504 /* RaisedButton.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RaisedButton.swift; path = Sources/iOS/RaisedButton.swift; sourceTree = ""; }; - 4431DCFCBEA896DEC8366BA082ED2692 /* KeyboardSpy.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = KeyboardSpy.modulemap; sourceTree = ""; }; - 4478B9BFEC84518FBF6BA118C1E6CB12 /* TextStorage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TextStorage.swift; path = Sources/iOS/TextStorage.swift; sourceTree = ""; }; - 45870C59B4C74A0325BB8E056C6D37E4 /* Material+UIView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Material+UIView.swift"; path = "Sources/iOS/Material+UIView.swift"; sourceTree = ""; }; - 46E85FD2A85A33D289BA7F89A35422AD /* UILayoutSupport+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UILayoutSupport+Extensions.swift"; path = "Source/UILayoutSupport+Extensions.swift"; sourceTree = ""; }; - 489E7C29FB18995359DF56C6CD587D22 /* ConstraintLayoutGuideDSL.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintLayoutGuideDSL.swift; path = Source/ConstraintLayoutGuideDSL.swift; sourceTree = ""; }; - 48C8DD3ADA21FEC1C19ADACF1DA4DEBD /* Switch.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Switch.swift; path = Sources/iOS/Switch.swift; sourceTree = ""; }; - 48EF6003775C91D21EB500BFDCB49075 /* Device.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Device.swift; path = Sources/iOS/Device.swift; sourceTree = ""; }; - 49464A1B46F964BB49A6CF2325EC1192 /* EditorController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = EditorController.swift; path = Sources/iOS/EditorController.swift; sourceTree = ""; }; - 497F6485F7A980F83AAB2472EF61D4DA /* SnapKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SnapKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 505A33EDE2771A4040D6809A7C7C66A4 /* NavigationController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NavigationController.swift; path = Sources/iOS/NavigationController.swift; sourceTree = ""; }; - 50793AF3E7D68DD48DE992F0E18E7B11 /* Layout.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Layout.swift; path = Sources/iOS/Layout.swift; sourceTree = ""; }; - 50C3D1709D201AB8633D3379DA9EB61D /* ConstraintMakerFinalizable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintMakerFinalizable.swift; path = Source/ConstraintMakerFinalizable.swift; sourceTree = ""; }; - 55296E0F08CC0C7F4232ED6333949D70 /* LayoutConstraintItem.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = LayoutConstraintItem.swift; path = Source/LayoutConstraintItem.swift; sourceTree = ""; }; - 56C2CD4361B65A92AF0CD0726C46C22C /* TableViewController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TableViewController.swift; path = Sources/iOS/TableViewController.swift; sourceTree = ""; }; - 59286B46714772F8B5110C675CA9E4E5 /* Constraint.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Constraint.swift; path = Source/Constraint.swift; sourceTree = ""; }; - 5986E6DD7BC1F388CC2A4C4A3E90482C /* ConstraintView+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ConstraintView+Extensions.swift"; path = "Source/ConstraintView+Extensions.swift"; sourceTree = ""; }; - 5B472103E56AC172D2C0BE714AA81690 /* Shape.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Shape.swift; path = Sources/iOS/Shape.swift; sourceTree = ""; }; + 2CE1FF341717F3DC7D7B063D6B0A0A86 /* SnapKit-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SnapKit-umbrella.h"; sourceTree = ""; }; + 2CEB59D9A8E5ACDAB622147C5DB59779 /* KeyboardSpy.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = KeyboardSpy.xcconfig; sourceTree = ""; }; + 333EC9315BA04B42207F035F62305FEB /* MotionAnimatorViewContext.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MotionAnimatorViewContext.swift; path = Sources/Frameworks/Motion/Sources/Animator/MotionAnimatorViewContext.swift; sourceTree = ""; }; + 336FBB6A87EDE9D9196BC57EA2101FD1 /* SnapKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SnapKit.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 338FE444D8BAFEBC0759FD9F96748DC7 /* MotionSnapshotType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MotionSnapshotType.swift; path = Sources/Frameworks/Motion/Sources/MotionSnapshotType.swift; sourceTree = ""; }; + 341D52075E4B522176783D1F09D77CBB /* NavigationController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NavigationController.swift; path = Sources/iOS/NavigationController.swift; sourceTree = ""; }; + 35127700E6E1FD5733A6BB805095905A /* Assets.xcassets */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Sources/Assets.xcassets; sourceTree = ""; }; + 36B37F159DFEF0BE9004762ECB656187 /* Motion+UIKit.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Motion+UIKit.swift"; path = "Sources/Frameworks/Motion/Sources/Extensions/Motion+UIKit.swift"; sourceTree = ""; }; + 3C221EEAAAE0F1EE0BD1DD752D7DE13D /* Material.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Material.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 3CA3D8AF992D96CE94963FF1839EEBFB /* Constraint.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Constraint.swift; path = Source/Constraint.swift; sourceTree = ""; }; + 3D81F6D5952A9F3A463C70D2BCF43E73 /* CollectionViewLayout.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CollectionViewLayout.swift; path = Sources/iOS/CollectionViewLayout.swift; sourceTree = ""; }; + 43DA5D78DA585F03E7335F023388071C /* TextStorage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TextStorage.swift; path = Sources/iOS/TextStorage.swift; sourceTree = ""; }; + 43EA7643013C12817DADAE6A56D144DA /* SnapKit-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SnapKit-prefix.pch"; sourceTree = ""; }; + 4693FC54E08F8CC0F4649066F0000071 /* SnapKit-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SnapKit-dummy.m"; sourceTree = ""; }; + 46A628B86F7E8DFD403412AD66BD0DC1 /* FlatButton.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FlatButton.swift; path = Sources/iOS/FlatButton.swift; sourceTree = ""; }; + 481F5B635615A26BA7F541FD8C4B3458 /* SnapKit.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SnapKit.xcconfig; sourceTree = ""; }; + 48270BDDE59DE398D04189141411D1AE /* Toolbar.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Toolbar.swift; path = Sources/iOS/Toolbar.swift; sourceTree = ""; }; + 483F5A2415D80218DBFD1FEB15DC3E02 /* ResourceBundle-com.cosmicmind.material.fonts-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-com.cosmicmind.material.fonts-Info.plist"; sourceTree = ""; }; + 487A400166FA22AD3E9B612510E7B7F1 /* MotionAnimationState.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MotionAnimationState.swift; path = Sources/Frameworks/Motion/Sources/MotionAnimationState.swift; sourceTree = ""; }; + 499408A4B19535EBD30AEA2EF4FB99C5 /* MotionAnimation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MotionAnimation.swift; path = Sources/Frameworks/Motion/Sources/MotionAnimation.swift; sourceTree = ""; }; + 4A081494ECAF4DF9F69FD642B5E83605 /* ChipBarController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ChipBarController.swift; path = Sources/iOS/ChipBarController.swift; sourceTree = ""; }; + 4A2AF3355A6B5F0EEE97C8A3ECAD9302 /* Pods_KeyboardSpy_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_KeyboardSpy_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 4A57C4B1BD27B48F524414DBD6A9AC1C /* ImageCard.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageCard.swift; path = Sources/iOS/ImageCard.swift; sourceTree = ""; }; + 4B1A517903796A6981BAE5E931900276 /* ConstraintPriorityTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintPriorityTarget.swift; path = Source/ConstraintPriorityTarget.swift; sourceTree = ""; }; + 4B7223A3519C06913B81B56CB2A3A39D /* ConstraintLayoutGuide+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ConstraintLayoutGuide+Extensions.swift"; path = "Source/ConstraintLayoutGuide+Extensions.swift"; sourceTree = ""; }; + 4CF77ADF624A2A645718F20F388FF409 /* BottomNavigationController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BottomNavigationController.swift; path = Sources/iOS/BottomNavigationController.swift; sourceTree = ""; }; + 4D67D847A76445CFABB19330480C5729 /* HeightPreset.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HeightPreset.swift; path = Sources/iOS/HeightPreset.swift; sourceTree = ""; }; + 4FE148A95C46F92A3BC9823F7A1C2D83 /* ConstraintLayoutGuide.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintLayoutGuide.swift; path = Source/ConstraintLayoutGuide.swift; sourceTree = ""; }; + 5067B551F58C6CBAF02AACA2588B3A2E /* NavigationBar.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NavigationBar.swift; path = Sources/iOS/NavigationBar.swift; sourceTree = ""; }; + 50C6E544D13AF514C77C14D5637E6FB8 /* ConstraintMakerFinalizable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintMakerFinalizable.swift; path = Source/ConstraintMakerFinalizable.swift; sourceTree = ""; }; + 512BDB7A758DDE4EE03731CCAB38EA6A /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 53693D841B2B8BCD50FC5A5EB1A7C254 /* Material+UIWindow.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Material+UIWindow.swift"; path = "Sources/iOS/Material+UIWindow.swift"; sourceTree = ""; }; + 55C850B0B5A8873EDC66B9853309D9D9 /* ConstraintOffsetTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintOffsetTarget.swift; path = Source/ConstraintOffsetTarget.swift; sourceTree = ""; }; + 562520D21C313BC739ADA36597DE7B37 /* View.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = View.swift; path = Sources/iOS/View.swift; sourceTree = ""; }; + 56A6EDBCEF4058D3E0479D91F7557D74 /* KeyboardSpyEvent.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KeyboardSpyEvent.swift; path = KeyboardSpy/Classes/KeyboardSpyEvent.swift; sourceTree = ""; }; + 58C29E8BB6FFFBF28CD92D380CAE0968 /* Motion.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Motion.swift; path = Sources/Frameworks/Motion/Sources/Motion.swift; sourceTree = ""; }; + 59FD8B4965A0D2142072455B539D3A3B /* Roboto-Thin.ttf */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = file; name = "Roboto-Thin.ttf"; path = "Sources/Font/Roboto/Roboto-Thin.ttf"; sourceTree = ""; }; + 59FD9FB5A3AD6E1E2456A1E9B770AD18 /* Roboto-Regular.ttf */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = file; name = "Roboto-Regular.ttf"; path = "Sources/Font/Roboto/Roboto-Regular.ttf"; sourceTree = ""; }; + 5A42AE8FC34C0BFCEB2CC540BF41F869 /* RaisedButton.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RaisedButton.swift; path = Sources/iOS/RaisedButton.swift; sourceTree = ""; }; + 5B0B36A7CE96D869B7ACBBB2EBDA905F /* FABButton.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FABButton.swift; path = Sources/iOS/FABButton.swift; sourceTree = ""; }; + 5B407895836E5055B827DDF5582B2F5E /* StatusBarController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = StatusBarController.swift; path = Sources/iOS/StatusBarController.swift; sourceTree = ""; }; + 5B6003FCCEBCB8E473887B41D4DCB25B /* MotionContext.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MotionContext.swift; path = Sources/Frameworks/Motion/Sources/MotionContext.swift; sourceTree = ""; }; + 5B962828A6BE66FBF013FB6CBC6C0376 /* SearchBarController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SearchBarController.swift; path = Sources/iOS/SearchBarController.swift; sourceTree = ""; }; 5BC139752F9C6FBD618F1A8861A42BEE /* Pods-KeyboardSpy_Example.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = "Pods-KeyboardSpy_Example.modulemap"; sourceTree = ""; }; - 5C299620A7769FA365FBAABDBE43A589 /* InterimSpace.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = InterimSpace.swift; path = Sources/iOS/InterimSpace.swift; sourceTree = ""; }; - 5C4C6087871B4325FCACD7729BCC7142 /* StatusBarController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = StatusBarController.swift; path = Sources/iOS/StatusBarController.swift; sourceTree = ""; }; + 5C611A36A6E9F1AC68597DA589384EFD /* ConstraintRelatableTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintRelatableTarget.swift; path = Source/ConstraintRelatableTarget.swift; sourceTree = ""; }; + 5C6FCC5CDB1D913BD264CDB67C86F4F4 /* MotionPlugin.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MotionPlugin.swift; path = Sources/Frameworks/Motion/Sources/MotionPlugin.swift; sourceTree = ""; }; + 5D080E614C5165DFBED6BFAACECE1CCB /* ConstraintItem.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintItem.swift; path = Source/ConstraintItem.swift; sourceTree = ""; }; + 5E61179943BBB611A1033CC48D39D0AC /* ResourceBundle-com.cosmicmind.material.icons-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-com.cosmicmind.material.icons-Info.plist"; sourceTree = ""; }; + 60259A0DAF13057DAC54F362932F7E52 /* CollectionViewController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CollectionViewController.swift; path = Sources/iOS/CollectionViewController.swift; sourceTree = ""; }; 60C56E9F90E6D90CF3FD96AFEC2B8699 /* Pods-KeyboardSpy_Example-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-KeyboardSpy_Example-dummy.m"; sourceTree = ""; }; - 612E855F09DF3C6FA7963B1503054960 /* BottomNavigationController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BottomNavigationController.swift; path = Sources/iOS/BottomNavigationController.swift; sourceTree = ""; }; - 613B5985B4FAAAE96C41D1FA839C9831 /* Toolbar.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Toolbar.swift; path = Sources/iOS/Toolbar.swift; sourceTree = ""; }; - 61CACCAFC625386A3516D06CE236C4BB /* Roboto-Bold.ttf */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = file; name = "Roboto-Bold.ttf"; path = "Sources/Font/Roboto/Roboto-Bold.ttf"; sourceTree = ""; }; - 627BC7E8A032AB69B428B18D377C8D3A /* Pods_KeyboardSpy_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_KeyboardSpy_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 64BA1C116C3994F81B5F80A6E2018179 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 6676636F44773FDE40C8FAF6D034419F /* RobotoFont.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RobotoFont.swift; path = Sources/iOS/RobotoFont.swift; sourceTree = ""; }; - 6922CFF6AB5A3AEB9320BC6491C95F06 /* SnapKit-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SnapKit-dummy.m"; sourceTree = ""; }; - 6C4D4BD2840EA90650FE252BB9693AE9 /* ConstraintMakerExtendable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintMakerExtendable.swift; path = Source/ConstraintMakerExtendable.swift; sourceTree = ""; }; - 6D5ECB44A26D6452B990344C6DE6925D /* Material+String.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Material+String.swift"; path = "Sources/iOS/Material+String.swift"; sourceTree = ""; }; - 6DEC520A57ED877D9E44252C8FD75A0B /* Color.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Color.swift; path = Sources/iOS/Color.swift; sourceTree = ""; }; - 6E8D72D2A07C4CFA4A4B47E70AD6813A /* IconButton.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IconButton.swift; path = Sources/iOS/IconButton.swift; sourceTree = ""; }; - 7240D4DDCA8892D9B103DD1144E016E9 /* Border.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Border.swift; path = Sources/iOS/Border.swift; sourceTree = ""; }; - 74D407BF89192F7B53EBC558741601A2 /* io.cosmicmind.material.icons.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = io.cosmicmind.material.icons.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; - 753507311BD88F21C5B570568F5405D7 /* Material+CALayer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Material+CALayer.swift"; path = "Sources/iOS/Material+CALayer.swift"; sourceTree = ""; }; - 76CDE54CBC0B523EFDE97856F05EA6CD /* ConstraintDescription.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintDescription.swift; path = Source/ConstraintDescription.swift; sourceTree = ""; }; - 786BC7BB1F427F271C44AD843AE23F6C /* Icon.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Icon.swift; path = Sources/iOS/Icon.swift; sourceTree = ""; }; - 793F6341BA6DD3253704E907314468D1 /* Material-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Material-prefix.pch"; sourceTree = ""; }; - 79F0B45651C9FD2AC25924E3217CA9B5 /* CollectionView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CollectionView.swift; path = Sources/iOS/CollectionView.swift; sourceTree = ""; }; - 7A6AFCED171C156CC0419667D864775C /* MenuController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MenuController.swift; path = Sources/iOS/MenuController.swift; sourceTree = ""; }; - 7B07B9C2E705FFD7BBF4A7E5A0183CBE /* Material-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Material-umbrella.h"; sourceTree = ""; }; - 7CF05888635DDB2556D5E540E1348DE2 /* ConstraintInsetTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintInsetTarget.swift; path = Source/ConstraintInsetTarget.swift; sourceTree = ""; }; - 7FBE2265884984A05086DD251FC5971A /* Material+Array.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Material+Array.swift"; path = "Sources/iOS/Material+Array.swift"; sourceTree = ""; }; - 828D6C8E170FA51D2D89BFEDD3C464F9 /* SnapKit-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SnapKit-umbrella.h"; sourceTree = ""; }; - 85315320E60D2D52CC7EAEBBC21463A6 /* ConstraintPriorityTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintPriorityTarget.swift; path = Source/ConstraintPriorityTarget.swift; sourceTree = ""; }; - 8574BF3D0680E8B3FF01479BC6E6030B /* ConstraintConstantTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintConstantTarget.swift; path = Source/ConstraintConstantTarget.swift; sourceTree = ""; }; - 878F505F2614FEFB68522649F4ACA208 /* Motion.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Motion.swift; path = Sources/iOS/Motion.swift; sourceTree = ""; }; + 62AA6DA8DD31877CCBED3B41BAE939C3 /* TextView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TextView.swift; path = Sources/iOS/TextView.swift; sourceTree = ""; }; + 6604A7D69453B4569E4E4827FB9155A9 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.3.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; + 66AA832FAEC662DFE2E79B120597DB97 /* PulseAnimation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PulseAnimation.swift; path = Sources/iOS/PulseAnimation.swift; sourceTree = ""; }; + 66BAB4D25B723308397559B82DC7B545 /* Color.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Color.swift; path = Sources/iOS/Color.swift; sourceTree = ""; }; + 6C1C187FD8952ED399F7B5EC47D4AA9C /* ConstraintMultiplierTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintMultiplierTarget.swift; path = Source/ConstraintMultiplierTarget.swift; sourceTree = ""; }; + 6F779C0647CC8D560F8253FCC53F4CB7 /* Divider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Divider.swift; path = Sources/iOS/Divider.swift; sourceTree = ""; }; + 6FE94E6DE0E4563E476761744B199D4F /* ConstraintLayoutSupport.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintLayoutSupport.swift; path = Source/ConstraintLayoutSupport.swift; sourceTree = ""; }; + 724F8483EBF2FD26F4D41D63F64B2220 /* CascadePreprocessor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CascadePreprocessor.swift; path = Sources/Frameworks/Motion/Sources/Preprocessors/CascadePreprocessor.swift; sourceTree = ""; }; + 744F73221AAB025C438C3CD405A68D67 /* SnackbarController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SnackbarController.swift; path = Sources/iOS/SnackbarController.swift; sourceTree = ""; }; + 746C113ED7D893C564FB2212795C20A9 /* KeyboardSpy-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "KeyboardSpy-umbrella.h"; sourceTree = ""; }; + 74CF9573521287109B626947CE07DFF4 /* MotionAnimationFillMode.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MotionAnimationFillMode.swift; path = Sources/Frameworks/Motion/Sources/Extensions/MotionAnimationFillMode.swift; sourceTree = ""; }; + 7554641F0543351CC1138CD54CA8EE01 /* Material.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Material.xcconfig; sourceTree = ""; }; + 7738D28DAE703698826FF9FC7C9AB092 /* TabsController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TabsController.swift; path = Sources/iOS/TabsController.swift; sourceTree = ""; }; + 789F24D8EB68E2D2479D47439BF3FFA1 /* Card.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Card.swift; path = Sources/iOS/Card.swift; sourceTree = ""; }; + 79553E00CC72D70AFF8BB193101579E2 /* CollectionReusableView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CollectionReusableView.swift; path = Sources/iOS/CollectionReusableView.swift; sourceTree = ""; }; + 7A4303A2BEA3726D0E5E09F049E7353E /* Icon.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Icon.swift; path = Sources/iOS/Icon.swift; sourceTree = ""; }; + 7BF349907A54AB4AB35912BB4297D237 /* IconButton.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IconButton.swift; path = Sources/iOS/IconButton.swift; sourceTree = ""; }; + 7C8884F6E1A3577084D069711AFA8A3D /* MotionTransitionAnimator.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MotionTransitionAnimator.swift; path = Sources/Frameworks/Motion/Sources/Animator/MotionTransitionAnimator.swift; sourceTree = ""; }; + 7CE5C53A344F86A38A3791DFD39984A0 /* ConstraintPriority.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintPriority.swift; path = Source/ConstraintPriority.swift; sourceTree = ""; }; + 7E09CD729CD53ECADE86C5CAA46AFEA2 /* Material+UIFont.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Material+UIFont.swift"; path = "Sources/iOS/Material+UIFont.swift"; sourceTree = ""; }; + 7E6BD2E15F44CC91A2451ACC85A5CF9A /* MotionIndependentController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MotionIndependentController.swift; path = Sources/Frameworks/Motion/Sources/MotionIndependentController.swift; sourceTree = ""; }; + 7F8B3AECB2CE612A01D32F93F28018A0 /* DynamicFontType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DynamicFontType.swift; path = Sources/iOS/DynamicFontType.swift; sourceTree = ""; }; + 802641A5CF1A76C57D3BB9B8ACFC012F /* Button.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Button.swift; path = Sources/iOS/Button.swift; sourceTree = ""; }; + 803EC022B8A7FF20442F8462F128CC47 /* TransitionController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TransitionController.swift; path = Sources/iOS/TransitionController.swift; sourceTree = ""; }; + 820338254434C6CB3C9C9ECC0D575906 /* Screen.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Screen.swift; path = Sources/iOS/Screen.swift; sourceTree = ""; }; + 8223A33C2D47D3C1DBC9D3AB5C7C0CDD /* Snackbar.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Snackbar.swift; path = Sources/iOS/Snackbar.swift; sourceTree = ""; }; + 82CC1F32060AEA7B22314F7F315C765C /* ConstraintInsets.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintInsets.swift; path = Source/ConstraintInsets.swift; sourceTree = ""; }; + 82EB798C1FB4D9EEA1F592220008F4DF /* NavigationItem.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NavigationItem.swift; path = Sources/iOS/NavigationItem.swift; sourceTree = ""; }; + 8655037FB101023F644AB93D46531E3B /* ConstraintLayoutSupportDSL.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintLayoutSupportDSL.swift; path = Source/ConstraintLayoutSupportDSL.swift; sourceTree = ""; }; 87A1E8AEDDBE8BFBB61DF644D5E89FBA /* Pods-KeyboardSpy_Example-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-KeyboardSpy_Example-acknowledgements.plist"; sourceTree = ""; }; - 8B2B6D02B41725C2F09C2C6A2CB90089 /* Material+UIImage.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Material+UIImage.swift"; path = "Sources/iOS/Material+UIImage.swift"; sourceTree = ""; }; - 8B7291744862FC3B943875334A37326F /* Display.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Display.swift; path = Sources/iOS/Display.swift; sourceTree = ""; }; - 8DC76F38419F33B61224B3BF03F60969 /* Material+Obj-C.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Material+Obj-C.swift"; path = "Sources/iOS/Material+Obj-C.swift"; sourceTree = ""; }; - 8DDDCB0C43CADB19A98F4338101C1168 /* KeyboardSpyAgent.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = KeyboardSpyAgent.swift; sourceTree = ""; }; - 8E0C2ECC32318E612A2616E4508C446C /* ConstraintAttributes.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintAttributes.swift; path = Source/ConstraintAttributes.swift; sourceTree = ""; }; - 8E3D61406E1A615B51C7DDEC3D0226AC /* CollectionViewCell.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CollectionViewCell.swift; path = Sources/iOS/CollectionViewCell.swift; sourceTree = ""; }; - 8FD66C72073ECAA2B4FE8D6303DE29D1 /* KeyboardSpy-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "KeyboardSpy-dummy.m"; sourceTree = ""; }; - 9186A695A6BC64DBBD46F73C55B7E9A0 /* SearchBar.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SearchBar.swift; path = Sources/iOS/SearchBar.swift; sourceTree = ""; }; + 898E73CD666E0111686A18C887582A52 /* ConstraintMakerRelatable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintMakerRelatable.swift; path = Source/ConstraintMakerRelatable.swift; sourceTree = ""; }; + 89E26B785FD84FC8ED6D7769EC994673 /* com.cosmicmind.material.fonts.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = com.cosmicmind.material.fonts.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + 8AD0C47E4179535B7CA07A252718D02B /* CornerRadius.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CornerRadius.swift; path = Sources/iOS/CornerRadius.swift; sourceTree = ""; }; + 8B21646206535ACA03016E06B41E7D2B /* TableViewCell.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TableViewCell.swift; path = Sources/iOS/TableViewCell.swift; sourceTree = ""; }; + 8BE935A6FC3B6BDA73FC5D76069040CB /* MotionHasInsertOrder.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MotionHasInsertOrder.swift; path = Sources/Frameworks/Motion/Sources/Animator/MotionHasInsertOrder.swift; sourceTree = ""; }; + 8BFDD5A0A8B86B89D8E34AD0D5E89885 /* CharacterAttribute.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CharacterAttribute.swift; path = Sources/iOS/CharacterAttribute.swift; sourceTree = ""; }; + 8F88EF8CD7E5ECCD9A2AE3D934B4B2A1 /* Motion+Array.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Motion+Array.swift"; path = "Sources/Frameworks/Motion/Sources/Extensions/Motion+Array.swift"; sourceTree = ""; }; + 90914AE4D3F87A0BDB6083372A492EDF /* MotionCoreAnimationViewContext.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MotionCoreAnimationViewContext.swift; path = Sources/Frameworks/Motion/Sources/Animator/MotionCoreAnimationViewContext.swift; sourceTree = ""; }; + 91356D8E95C500958415574ED91CF53C /* Layer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Layer.swift; path = Sources/iOS/Layer.swift; sourceTree = ""; }; + 916E6656F4A77EDA6ACF9C11736B9520 /* Material+UIViewController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Material+UIViewController.swift"; path = "Sources/iOS/Material+UIViewController.swift"; sourceTree = ""; }; 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; - 93D28BF617451FBF9A50EF928B8C6D75 /* Material.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = Material.xcconfig; sourceTree = ""; }; - 94FC1BA9ABCA485F6C57ED94897F58A5 /* Editor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Editor.swift; path = Sources/iOS/Editor.swift; sourceTree = ""; }; - 9818E677DDAF7ED27910C966923CABEB /* TabBar.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TabBar.swift; path = Sources/iOS/TabBar.swift; sourceTree = ""; }; - 998AD3233A9E4B030C240E4EA3323378 /* ConstraintRelation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintRelation.swift; path = Source/ConstraintRelation.swift; sourceTree = ""; }; - 9BCCE7C2B99E6EAF7C935B30D8099848 /* TextField.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TextField.swift; path = Sources/iOS/TextField.swift; sourceTree = ""; }; - A183AB8864CA6D36905EFBAFE72328C2 /* RootController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RootController.swift; path = Sources/iOS/RootController.swift; sourceTree = ""; }; - A3602387B591F81169705905D0F11DFC /* ConstraintLayoutGuide+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ConstraintLayoutGuide+Extensions.swift"; path = "Source/ConstraintLayoutGuide+Extensions.swift"; sourceTree = ""; }; - A4649840170D6AA34B847908C8F4A7BA /* TableViewCell.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TableViewCell.swift; path = Sources/iOS/TableViewCell.swift; sourceTree = ""; }; - A50ABC396DD22F4FFF7DEC63DA7E7C0F /* ConstraintOffsetTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintOffsetTarget.swift; path = Source/ConstraintOffsetTarget.swift; sourceTree = ""; }; - A7574F5A7DA17DA8433B68FEC4D8E2B4 /* SearchBarController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SearchBarController.swift; path = Sources/iOS/SearchBarController.swift; sourceTree = ""; }; - AA4DA8C856465AF25613B8DE31FA29F9 /* Roboto-Regular.ttf */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = file; name = "Roboto-Regular.ttf"; path = "Sources/Font/Roboto/Roboto-Regular.ttf"; sourceTree = ""; }; - AD65A1EB0EC10BBA9A12B7702A44BEE1 /* EdgeInsets.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = EdgeInsets.swift; path = Sources/iOS/EdgeInsets.swift; sourceTree = ""; }; - AEB86F4BEDAB8E00CC260345E812888F /* SnapKit-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SnapKit-prefix.pch"; sourceTree = ""; }; + 950728AD99C523FE9AC4AF021A912D98 /* CardCollectionViewController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CardCollectionViewController.swift; path = Sources/iOS/CardCollectionViewController.swift; sourceTree = ""; }; + 96C22AFB26EE0F5060AC4A1773505C2A /* Material+Array.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Material+Array.swift"; path = "Sources/iOS/Material+Array.swift"; sourceTree = ""; }; + 96D9601403ED520105BF0F34E0F63125 /* ConstraintAttributes.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintAttributes.swift; path = Source/ConstraintAttributes.swift; sourceTree = ""; }; + 984BDCC45A221413BAE5828C619531AD /* ConstraintMakerExtendable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintMakerExtendable.swift; path = Source/ConstraintMakerExtendable.swift; sourceTree = ""; }; + 997E15A2B422B6F94889B04D865E0D1D /* ErrorTextField.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ErrorTextField.swift; path = Sources/iOS/ErrorTextField.swift; sourceTree = ""; }; + 9A5E3544BD773E033215450E9F0FBFD5 /* PresenterCard.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PresenterCard.swift; path = Sources/iOS/PresenterCard.swift; sourceTree = ""; }; + 9A9479DAE0B452979DFBF59758339AE2 /* Depth.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Depth.swift; path = Sources/iOS/Depth.swift; sourceTree = ""; }; + 9DDA18D5E5704B28AE964CB185FB2F81 /* Material+String.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Material+String.swift"; path = "Sources/iOS/Material+String.swift"; sourceTree = ""; }; + 9E33F9931AA03B2C728FF889D2CA2835 /* NavigationDrawerController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NavigationDrawerController.swift; path = Sources/iOS/NavigationDrawerController.swift; sourceTree = ""; }; + 9EFEA8D85BFC2CD4BE60F580567556A2 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 9FBDADDBB78E63A6F8F536C1A8A1BF6C /* InterimSpace.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = InterimSpace.swift; path = Sources/iOS/InterimSpace.swift; sourceTree = ""; }; + A240F13043E832ED2C0DE4197F53986C /* MotionAnimator.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MotionAnimator.swift; path = Sources/Frameworks/Motion/Sources/Animator/MotionAnimator.swift; sourceTree = ""; }; + A49A02172E372515A37DFB2B609B718F /* TransitionPreprocessor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TransitionPreprocessor.swift; path = Sources/Frameworks/Motion/Sources/Preprocessors/TransitionPreprocessor.swift; sourceTree = ""; }; + A6663232B21A072859EDE9347DEA9C07 /* Device.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Device.swift; path = Sources/iOS/Device.swift; sourceTree = ""; }; + A795AFA4EFBE1DC0CDF4312824621FCB /* Material+CALayer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Material+CALayer.swift"; path = "Sources/iOS/Material+CALayer.swift"; sourceTree = ""; }; + A98FA3A05CCC692F52ADFBC6D639731F /* CardCollectionViewCell.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CardCollectionViewCell.swift; path = Sources/iOS/CardCollectionViewCell.swift; sourceTree = ""; }; + A999BD3B694EF67F9145508F09E45B95 /* ConstraintMakerPriortizable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintMakerPriortizable.swift; path = Source/ConstraintMakerPriortizable.swift; sourceTree = ""; }; + AEC428ECD599B5F5E5D6366D3D812BE8 /* ConstraintViewDSL.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintViewDSL.swift; path = Source/ConstraintViewDSL.swift; sourceTree = ""; }; + B17790D1A558455995AD12F9838E4AFE /* Motion+UIView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Motion+UIView.swift"; path = "Sources/Frameworks/Motion/Sources/Extensions/Motion+UIView.swift"; sourceTree = ""; }; + B1D14CD0FA0EA6589A755F5E831231F9 /* Layout.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Layout.swift; path = Sources/iOS/Layout.swift; sourceTree = ""; }; + B2EC919E0280AFAFAB77B12431195872 /* Offset.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Offset.swift; path = Sources/iOS/Offset.swift; sourceTree = ""; }; B3B937BCC6657E47A8E865D991C0864D /* Pods-KeyboardSpy_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-KeyboardSpy_Example.debug.xcconfig"; sourceTree = ""; }; - B6CAADE0822269FB6362B3FFECAECB42 /* Grid.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Grid.swift; path = Sources/iOS/Grid.swift; sourceTree = ""; }; - B8EEAE6D6FDAB8AEF9F638C3F10535D1 /* Button.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Button.swift; path = Sources/iOS/Button.swift; sourceTree = ""; }; - B99D67DEFF46F955A0A4388075807446 /* MenuItem.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MenuItem.swift; path = Sources/iOS/MenuItem.swift; sourceTree = ""; }; - BD437F3EDD3EA9947C1B479CD2C33F43 /* FlatButton.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FlatButton.swift; path = Sources/iOS/FlatButton.swift; sourceTree = ""; }; - BF1A2FBEF5874FE986CD9FC93B60615B /* ImageCard.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ImageCard.swift; path = Sources/iOS/ImageCard.swift; sourceTree = ""; }; - BF75F63D1E73F0F69739117868966536 /* NavigationDrawerController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NavigationDrawerController.swift; path = Sources/iOS/NavigationDrawerController.swift; sourceTree = ""; }; - C109BCAE67952558B9CA8F092EA9A567 /* ConstraintItem.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintItem.swift; path = Source/ConstraintItem.swift; sourceTree = ""; }; - C1741A06B2D81CA2FB171505DB8B09E5 /* CharacterAttribute.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CharacterAttribute.swift; path = Sources/iOS/CharacterAttribute.swift; sourceTree = ""; }; - C22D49D3B14F027CBDEB32F3BB68C732 /* DynamicFontType.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DynamicFontType.swift; path = Sources/iOS/DynamicFontType.swift; sourceTree = ""; }; - C38ED1097907390971ADB39EE1414567 /* MotionBasic.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MotionBasic.swift; path = Sources/iOS/MotionBasic.swift; sourceTree = ""; }; - C3D946174F3E557CD4FC1132C6314EF9 /* TableView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TableView.swift; path = Sources/iOS/TableView.swift; sourceTree = ""; }; - C4E7866B84F0604D70EFAEE508EBB335 /* Application.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Application.swift; path = Sources/iOS/Application.swift; sourceTree = ""; }; - C4F9036CDCA9314E9334D6B4ACB7B1BD /* KeyboardSpy-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "KeyboardSpy-prefix.pch"; sourceTree = ""; }; - C5A40C702BB4A49D472EAA6CFF62F736 /* Menu.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Menu.swift; path = Sources/iOS/Menu.swift; sourceTree = ""; }; - C6CCDA7C0486BEA2F243119352DFAC83 /* ConstraintMultiplierTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintMultiplierTarget.swift; path = Source/ConstraintMultiplierTarget.swift; sourceTree = ""; }; - C778F6DF76306DC29E9B8555ADDA1D55 /* Font.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Font.swift; path = Sources/iOS/Font.swift; sourceTree = ""; }; - C8C4D638529F47D744014C0A1ACFD2B8 /* Assets.xcassets */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Sources/Assets.xcassets; sourceTree = ""; }; - C919D01AC4B24B49FC0A9DEE866669D9 /* SnackbarController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SnackbarController.swift; path = Sources/iOS/SnackbarController.swift; sourceTree = ""; }; + B3D1DD856F87114CC8EB82FC2F806085 /* KeyboardSpy.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = KeyboardSpy.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + B5FC610D3C48E59F922BB216202B7B42 /* ConstraintMaker.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintMaker.swift; path = Source/ConstraintMaker.swift; sourceTree = ""; }; + B79769A1E065BEE70DED915FB67360BA /* Motion+CALayer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Motion+CALayer.swift"; path = "Sources/Frameworks/Motion/Sources/Extensions/Motion+CALayer.swift"; sourceTree = ""; }; + BB04C0C99C8D6CF1DE9805D6EB74578D /* Material+MotionAnimation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Material+MotionAnimation.swift"; path = "Sources/iOS/Material+MotionAnimation.swift"; sourceTree = ""; }; + BB514EB93F1D1F059B49B8382FEBD7EF /* MotionTransitionObserver.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MotionTransitionObserver.swift; path = Sources/Frameworks/Motion/Sources/MotionTransitionObserver.swift; sourceTree = ""; }; + BE4266C158269835E765361130F0558A /* KeyboardSpy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KeyboardSpy.swift; path = KeyboardSpy/Classes/KeyboardSpy.swift; sourceTree = ""; }; + BF8D02890D88B7DD533215654556DF09 /* ConstraintConstantTarget.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintConstantTarget.swift; path = Source/ConstraintConstantTarget.swift; sourceTree = ""; }; + C0833A6504E0C528A274EE2E3695DE5B /* DataSourceItem.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DataSourceItem.swift; path = Sources/iOS/DataSourceItem.swift; sourceTree = ""; }; + C3B704A01CFF273B6E6817C31A201649 /* ChipBar.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ChipBar.swift; path = Sources/iOS/ChipBar.swift; sourceTree = ""; }; + C3D6B71FE7158E9A18B8BC31D2A0C0C3 /* Grid.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Grid.swift; path = Sources/iOS/Grid.swift; sourceTree = ""; }; + C49A43F3F33E4F98D64440EEBA7CAF31 /* com.cosmicmind.material.icons.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = com.cosmicmind.material.icons.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + C4FE4756F341027C2CA36BFB29AD3FED /* FABMenu.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FABMenu.swift; path = Sources/iOS/FABMenu.swift; sourceTree = ""; }; + C54DC92432F36790BD880DD997A13397 /* ConstraintDescription.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintDescription.swift; path = Source/ConstraintDescription.swift; sourceTree = ""; }; + C61EE6C02AE9902C041D6D8B3D67D533 /* TextField.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TextField.swift; path = Sources/iOS/TextField.swift; sourceTree = ""; }; + C7B2A2CEE688E7FBE29FB8C7C6C9C14C /* Motion+CG.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Motion+CG.swift"; path = "Sources/Frameworks/Motion/Sources/Extensions/Motion+CG.swift"; sourceTree = ""; }; + C807F9DBF420871936843B8A0FC1736E /* Gravity.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Gravity.swift; path = Sources/iOS/Gravity.swift; sourceTree = ""; }; + C82088279A7BAC2ACA71BD231A794B45 /* Motion+CAMediaTimingFunction.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Motion+CAMediaTimingFunction.swift"; path = "Sources/Frameworks/Motion/Sources/Extensions/Motion+CAMediaTimingFunction.swift"; sourceTree = ""; }; + C8B031678B3CB8D481599EACA7794892 /* UILayoutSupport+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "UILayoutSupport+Extensions.swift"; path = "Source/UILayoutSupport+Extensions.swift"; sourceTree = ""; }; C9E5931023C63947A496AFF951F5A652 /* Pods-KeyboardSpy_Example-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-KeyboardSpy_Example-frameworks.sh"; sourceTree = ""; }; - CA9FF9A7B6D98C503DCB035D4E4B9833 /* KeyboardSpy.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = KeyboardSpy.xcconfig; sourceTree = ""; }; - CD409C9F625BE16AA14A0059481BC570 /* ConstraintLayoutSupportDSL.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintLayoutSupportDSL.swift; path = Source/ConstraintLayoutSupportDSL.swift; sourceTree = ""; }; - CEC22C73C1608DFA5D5D78BDCB218219 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS9.3.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; - CF8F89D38616DD8F9464D1E50D9B6FA2 /* ConstraintDSL.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintDSL.swift; path = Source/ConstraintDSL.swift; sourceTree = ""; }; - D04E0FAEA80A394C9A0A29DF0BC13409 /* KeyboardSpyEvent.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = KeyboardSpyEvent.swift; sourceTree = ""; }; - D2731D6D3B684A540BE1BD3AC680272A /* ResourceBundle-io.cosmicmind.material.fonts-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-io.cosmicmind.material.fonts-Info.plist"; sourceTree = ""; }; - D3A10EE0EC0560A2EC2BFD40D0CF5E18 /* Offset.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Offset.swift; path = Sources/iOS/Offset.swift; sourceTree = ""; }; - D6CF9A0DDB142AF7D40E293FDA149E77 /* Layer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Layer.swift; path = Sources/iOS/Layer.swift; sourceTree = ""; }; - D8083DE096D06A9A9755F0A0620AB65A /* Roboto-Thin.ttf */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = file; name = "Roboto-Thin.ttf"; path = "Sources/Font/Roboto/Roboto-Thin.ttf"; sourceTree = ""; }; - D8B8102C24675A4EAA37F43B5F41CE68 /* Material.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = Material.modulemap; sourceTree = ""; }; - D90050DEF76E42795A7B6EF2EF100A07 /* MotionKeyframe.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MotionKeyframe.swift; path = Sources/iOS/MotionKeyframe.swift; sourceTree = ""; }; - DA6851721F6547D80E863DAFD32DCC41 /* Divider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Divider.swift; path = Sources/iOS/Divider.swift; sourceTree = ""; }; - DDA8FD3FB1F7D42831F715F9F26C61E5 /* ResourceBundle-io.cosmicmind.material.icons-Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "ResourceBundle-io.cosmicmind.material.icons-Info.plist"; sourceTree = ""; }; - E22BF5FC7BE90AB43E1CBA18E2376C02 /* Debugging.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Debugging.swift; path = Source/Debugging.swift; sourceTree = ""; }; - E69D706A31179C60D704A37D72E084CB /* ConstraintConfig.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintConfig.swift; path = Source/ConstraintConfig.swift; sourceTree = ""; }; - ECCA7A951804AC16FC98668C19F8A40E /* HeightPreset.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = HeightPreset.swift; path = Sources/iOS/HeightPreset.swift; sourceTree = ""; }; - ECDFDEA96FCE7CAF30D9B87FBF15F7D2 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - ED42050548213D1CAF29D3ED249A98FF /* Depth.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Depth.swift; path = Sources/iOS/Depth.swift; sourceTree = ""; }; - ED97A6BBA65BBA334E662ECA9E02B06E /* KeyboardSpy-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "KeyboardSpy-umbrella.h"; sourceTree = ""; }; + CB366C6E4CB22A702214AC19A28C3145 /* KeyboardSpy.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = KeyboardSpy.modulemap; sourceTree = ""; }; + CBAC8A27D3958D51129ADE237A6BB871 /* MatchPreprocessor.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MatchPreprocessor.swift; path = Sources/Frameworks/Motion/Sources/Preprocessors/MatchPreprocessor.swift; sourceTree = ""; }; + CC2A7794E9A8E4BF593E8BEA3CC13F9A /* MotionController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MotionController.swift; path = Sources/Frameworks/Motion/Sources/MotionController.swift; sourceTree = ""; }; + CE11A03BFD1F047DF81CE5D8DB7255A7 /* ConstraintRelation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintRelation.swift; path = Source/ConstraintRelation.swift; sourceTree = ""; }; + CFFD8A5A2C59A73F737A1845C022FA12 /* DisplayStyle.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DisplayStyle.swift; path = Sources/iOS/DisplayStyle.swift; sourceTree = ""; }; + D012601CD0E44779C7B38BACB100B084 /* Material+UIView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Material+UIView.swift"; path = "Sources/iOS/Material+UIView.swift"; sourceTree = ""; }; + D27978F3C1B67B34E354A66CA7A4F3E1 /* TabBar.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TabBar.swift; path = Sources/iOS/TabBar.swift; sourceTree = ""; }; + D3A35CC89BE0B3799F6CC1D2AD20AEC3 /* CollectionViewCell.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CollectionViewCell.swift; path = Sources/iOS/CollectionViewCell.swift; sourceTree = ""; }; + D574C53286086E5ADCBC3B2172BB541D /* SpringAnimation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SpringAnimation.swift; path = Sources/iOS/SpringAnimation.swift; sourceTree = ""; }; + D5C87256138351F320508FE53BD4C7BB /* Roboto-Light.ttf */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = file; name = "Roboto-Light.ttf"; path = "Sources/Font/Roboto/Roboto-Light.ttf"; sourceTree = ""; }; + DB89BE5CF96047F5BB17B37983B6D44F /* ConstraintMakerEditable.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintMakerEditable.swift; path = Source/ConstraintMakerEditable.swift; sourceTree = ""; }; + DC9176A07A09F160CAEFC9731FB3E9B5 /* KeyboardSpy-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "KeyboardSpy-prefix.pch"; sourceTree = ""; }; + DD1440E42271BB98ED919BE226C8C8A7 /* ConstraintView+Extensions.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "ConstraintView+Extensions.swift"; path = "Source/ConstraintView+Extensions.swift"; sourceTree = ""; }; + DF1EDDBFF8C329BD4F24163606F15863 /* Motion+Obj-C.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Motion+Obj-C.swift"; path = "Sources/Frameworks/Motion/Sources/Extensions/Motion+Obj-C.swift"; sourceTree = ""; }; + E1A932A7AB1D47B56E9F950843DD50C1 /* MotionCAAnimation.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MotionCAAnimation.swift; path = Sources/Frameworks/Motion/Sources/MotionCAAnimation.swift; sourceTree = ""; }; + E22CD3715683FC8F8421450810107AF5 /* Motion+UIViewController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = "Motion+UIViewController.swift"; path = "Sources/Frameworks/Motion/Sources/Extensions/Motion+UIViewController.swift"; sourceTree = ""; }; + E3E8770F8014FD52A4063DDCBF99F3AF /* ConstraintLayoutGuideDSL.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintLayoutGuideDSL.swift; path = Source/ConstraintLayoutGuideDSL.swift; sourceTree = ""; }; + E56D6440BE5F3B60407251179CAD03A3 /* Roboto-Medium.ttf */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = file; name = "Roboto-Medium.ttf"; path = "Sources/Font/Roboto/Roboto-Medium.ttf"; sourceTree = ""; }; + E775BC5710D5B314EEEB3F6863B2554B /* SnapKit.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = "sourcecode.module-map"; path = SnapKit.modulemap; sourceTree = ""; }; + E82E40F4B23B27C90916581A7B4092DF /* LayoutConstraintItem.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = LayoutConstraintItem.swift; path = Source/LayoutConstraintItem.swift; sourceTree = ""; }; + EB02DAC86275C42724DEAE2F9FE4E176 /* Debugging.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Debugging.swift; path = Source/Debugging.swift; sourceTree = ""; }; + EDDDE5E1B478A07CA02F3DDFEB4E2B2E /* KeyboardSpyAgent.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = KeyboardSpyAgent.swift; path = KeyboardSpy/Classes/KeyboardSpyAgent.swift; sourceTree = ""; }; + EE1E7A093AB064438C67A655C6046BE2 /* Material-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Material-prefix.pch"; sourceTree = ""; }; EE8F4318B6998AD8B763D75C3C2779DD /* Pods-KeyboardSpy_Example-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-KeyboardSpy_Example-umbrella.h"; sourceTree = ""; }; EEC8048D26BE41DA34C13CE490117424 /* Pods-KeyboardSpy_Example-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-KeyboardSpy_Example-acknowledgements.markdown"; sourceTree = ""; }; - F28A4A59DA2F7FBAF40E1ADD8A668F21 /* Gravity.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Gravity.swift; path = Sources/iOS/Gravity.swift; sourceTree = ""; }; - F29DD185D104269D36618B26571B0522 /* Snackbar.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Snackbar.swift; path = Sources/iOS/Snackbar.swift; sourceTree = ""; }; - F40232B8523F1EA8697CBB582CA1F105 /* ConstraintMaker.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ConstraintMaker.swift; path = Source/ConstraintMaker.swift; sourceTree = ""; }; - F4790179B22BE39130F0A994A92A4F2D /* ToolbarController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ToolbarController.swift; path = Sources/iOS/ToolbarController.swift; sourceTree = ""; }; - F6039EE99F67816635C75BE125A56BF2 /* View.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = View.swift; path = Sources/iOS/View.swift; sourceTree = ""; }; - F6EFF83DEE934EA35FEDB304725A8F99 /* Roboto-Light.ttf */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = file; name = "Roboto-Light.ttf"; path = "Sources/Font/Roboto/Roboto-Light.ttf"; sourceTree = ""; }; - F92385CDBFE17EE69610B27067AC7FCE /* KeyboardSpy.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; path = KeyboardSpy.swift; sourceTree = ""; }; - FB03BCD3478615E5CEAF3428ED0E51EE /* MotionPulse.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MotionPulse.swift; path = Sources/iOS/MotionPulse.swift; sourceTree = ""; }; + EFD6D0315D42263212698DD1E325BC26 /* EdgeInsets.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = EdgeInsets.swift; path = Sources/iOS/EdgeInsets.swift; sourceTree = ""; }; + EFE796CA3ECFC814DDF9D7EB147F9924 /* Application.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Application.swift; path = Sources/iOS/Application.swift; sourceTree = ""; }; + F147E88F444EB0CC44F735B0844EC33F /* Shape.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = Shape.swift; path = Sources/iOS/Shape.swift; sourceTree = ""; }; + F1C686E4EAE28D0BE02E823A6B18FB81 /* Material-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Material-dummy.m"; sourceTree = ""; }; + F33DF18C8CC85F9333323B05E2BCFDBC /* MotionTransition.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MotionTransition.swift; path = Sources/Frameworks/Motion/Sources/MotionTransition.swift; sourceTree = ""; }; + F66BF21C7F9438187C912CF65A4F61B8 /* PulseView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PulseView.swift; path = Sources/iOS/PulseView.swift; sourceTree = ""; }; FD3F616B16132DDE936432DFD5323DAF /* Pods-KeyboardSpy_Example-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-KeyboardSpy_Example-resources.sh"; sourceTree = ""; }; + FD4A4E8CE120E15B55290A847452C225 /* MotionCoordinateSpace.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = MotionCoordinateSpace.swift; path = Sources/Frameworks/Motion/Sources/MotionCoordinateSpace.swift; sourceTree = ""; }; + FE42BE25C4F00855A05A62C8BE5AF0A3 /* CollectionView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = CollectionView.swift; path = Sources/iOS/CollectionView.swift; sourceTree = ""; }; + FF064103CED8717386EE459CA9A3FBFB /* FABMenuController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = FABMenuController.swift; path = Sources/iOS/FABMenuController.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ - 026C5E63E1CE6543E4FAAA53B0829C84 /* Frameworks */ = { + 3B857261449ACF71DBA28CAED042C611 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 3E2271B883D9395EAF32726B4AAD33B2 /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - 0847FA7176FA5F8A726CA1BC356543E9 /* Frameworks */ = { + 6E9307AB48EFF5D40659A36A82396C2E /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 3E36BB00F7B283FF631B274034EB0DA9 /* Foundation.framework in Frameworks */, + E996062345CFA8AA6CE4C411DD56C535 /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - 69DF737A5588C675242D141CC39C2362 /* Frameworks */ = { + 7D866B8D4F4E2D07C95C784AA706D0A1 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - C1C9095E3C364CD535400E1417934B0D /* Frameworks */ = { + C856AA90E251A11ADCA37EA2D4A83E90 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 0730F0AF3DFBFC1D450004446C6EC95E /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - CC4987E463FF6FAD2A219B76D3D32069 /* Frameworks */ = { + F7298E1CBF7FC5C57D86A36136D48625 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 8337E13F01E3FCA88A188BA0D21DFC1E /* Foundation.framework in Frameworks */, + 2E8E0C87F71F29E3130A52EAC8C7E4CC /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; - E259225F6411EF111405F5F6E6CE0BE9 /* Frameworks */ = { + FA2ABA9162802D388565A7DD88ED44D4 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 603CD5E323F371AE272D9A985B5BF498 /* Foundation.framework in Frameworks */, + 7D7E11AD1344976DB0D9DD68DB3C4058 /* Foundation.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -418,416 +488,432 @@ path = "Target Support Files/Pods-KeyboardSpy_Example"; sourceTree = ""; }; - 3DCAB2B7CDE207B3958B6CB957FCC758 /* iOS */ = { + 503FF2E1070BAB93E1A9254A7553B2C1 /* KeyboardSpy */ = { isa = PBXGroup; children = ( - CEC22C73C1608DFA5D5D78BDCB218219 /* Foundation.framework */, + BE4266C158269835E765361130F0558A /* KeyboardSpy.swift */, + EDDDE5E1B478A07CA02F3DDFEB4E2B2E /* KeyboardSpyAgent.swift */, + 56A6EDBCEF4058D3E0479D91F7557D74 /* KeyboardSpyEvent.swift */, + 106445DF942638829B116010BC1317EB /* KeyboardSpyInfo.swift */, + 528E93BBC541A0A42DE70D37245C8509 /* Support Files */, ); - name = iOS; - sourceTree = ""; - }; - 3DF463463D5F25F45A00CCA128ACFFD3 /* Core */ = { - isa = PBXGroup; - children = ( - C4E7866B84F0604D70EFAEE508EBB335 /* Application.swift */, - 197255497D2A67D6A76D54E75E642BF7 /* Bar.swift */, - 7240D4DDCA8892D9B103DD1144E016E9 /* Border.swift */, - 612E855F09DF3C6FA7963B1503054960 /* BottomNavigationController.swift */, - 1AB532552FB417CAD645F0C6B302AFA3 /* BottomTabBar.swift */, - B8EEAE6D6FDAB8AEF9F638C3F10535D1 /* Button.swift */, - 11210AFBDE6150A11B9352BE81DB9B59 /* Card.swift */, - C1741A06B2D81CA2FB171505DB8B09E5 /* CharacterAttribute.swift */, - 058D958E907406F5AA26CAF6CF734232 /* CollectionReusableView.swift */, - 79F0B45651C9FD2AC25924E3217CA9B5 /* CollectionView.swift */, - 8E3D61406E1A615B51C7DDEC3D0226AC /* CollectionViewCell.swift */, - 0F8BEA1E432AF10F8BCF4AB7B0D887BA /* CollectionViewController.swift */, - 278611B3D38290F130D90B40ECB99C02 /* CollectionViewLayout.swift */, - 6DEC520A57ED877D9E44252C8FD75A0B /* Color.swift */, - 23C6DA2BCB6964F446E9085159C902AB /* CornerRadius.swift */, - 26CD3924B311AABDFC52C4181FF68410 /* DataSourceItem.swift */, - ED42050548213D1CAF29D3ED249A98FF /* Depth.swift */, - 48EF6003775C91D21EB500BFDCB49075 /* Device.swift */, - 8B7291744862FC3B943875334A37326F /* Display.swift */, - DA6851721F6547D80E863DAFD32DCC41 /* Divider.swift */, - C22D49D3B14F027CBDEB32F3BB68C732 /* DynamicFontType.swift */, - AD65A1EB0EC10BBA9A12B7702A44BEE1 /* EdgeInsets.swift */, - 94FC1BA9ABCA485F6C57ED94897F58A5 /* Editor.swift */, - 49464A1B46F964BB49A6CF2325EC1192 /* EditorController.swift */, - 3E3F318769C538096A7AF92767CD5E67 /* ErrorTextField.swift */, - 22FF2B67C144E96CBCDA8E4B0DBBFB60 /* FabButton.swift */, - BD437F3EDD3EA9947C1B479CD2C33F43 /* FlatButton.swift */, - C778F6DF76306DC29E9B8555ADDA1D55 /* Font.swift */, - F28A4A59DA2F7FBAF40E1ADD8A668F21 /* Gravity.swift */, - B6CAADE0822269FB6362B3FFECAECB42 /* Grid.swift */, - ECCA7A951804AC16FC98668C19F8A40E /* HeightPreset.swift */, - 786BC7BB1F427F271C44AD843AE23F6C /* Icon.swift */, - 6E8D72D2A07C4CFA4A4B47E70AD6813A /* IconButton.swift */, - BF1A2FBEF5874FE986CD9FC93B60615B /* ImageCard.swift */, - 5C299620A7769FA365FBAABDBE43A589 /* InterimSpace.swift */, - D6CF9A0DDB142AF7D40E293FDA149E77 /* Layer.swift */, - 50793AF3E7D68DD48DE992F0E18E7B11 /* Layout.swift */, - 7FBE2265884984A05086DD251FC5971A /* Material+Array.swift */, - 753507311BD88F21C5B570568F5405D7 /* Material+CALayer.swift */, - 8DC76F38419F33B61224B3BF03F60969 /* Material+Obj-C.swift */, - 6D5ECB44A26D6452B990344C6DE6925D /* Material+String.swift */, - 04F5D2F7D208372B8E2D22C1AEEA8424 /* Material+UIFont.swift */, - 8B2B6D02B41725C2F09C2C6A2CB90089 /* Material+UIImage.swift */, - 45870C59B4C74A0325BB8E056C6D37E4 /* Material+UIView.swift */, - 39CA1D743E25A38354A5D1C016E73BBC /* Material+UIWindow.swift */, - C5A40C702BB4A49D472EAA6CFF62F736 /* Menu.swift */, - 7A6AFCED171C156CC0419667D864775C /* MenuController.swift */, - B99D67DEFF46F955A0A4388075807446 /* MenuItem.swift */, - 878F505F2614FEFB68522649F4ACA208 /* Motion.swift */, - C38ED1097907390971ADB39EE1414567 /* MotionBasic.swift */, - D90050DEF76E42795A7B6EF2EF100A07 /* MotionKeyframe.swift */, - FB03BCD3478615E5CEAF3428ED0E51EE /* MotionPulse.swift */, - 35816A481311F72E21C7D87A865527A3 /* MotionTransition.swift */, - 188202353462A51F258C407A71543BDF /* NavigationBar.swift */, - 505A33EDE2771A4040D6809A7C7C66A4 /* NavigationController.swift */, - BF75F63D1E73F0F69739117868966536 /* NavigationDrawerController.swift */, - 21DFF42FFAC4B40307FF15FAC49E2087 /* NavigationItem.swift */, - D3A10EE0EC0560A2EC2BFD40D0CF5E18 /* Offset.swift */, - 1AA631E65680AB84D04DA6E325AC5149 /* PageTabBarController.swift */, - 060FB1C443967E5FB108D964A3315244 /* PresenterCard.swift */, - 01E281BC27F0ADF6A78211E32A61BE7F /* PulseView.swift */, - 43C21D605ED19DF26BCA60B7A8FA9504 /* RaisedButton.swift */, - 6676636F44773FDE40C8FAF6D034419F /* RobotoFont.swift */, - A183AB8864CA6D36905EFBAFE72328C2 /* RootController.swift */, - 2EA88863FE5C899F0B300BB6271371DE /* Screen.swift */, - 9186A695A6BC64DBBD46F73C55B7E9A0 /* SearchBar.swift */, - A7574F5A7DA17DA8433B68FEC4D8E2B4 /* SearchBarController.swift */, - 5B472103E56AC172D2C0BE714AA81690 /* Shape.swift */, - F29DD185D104269D36618B26571B0522 /* Snackbar.swift */, - C919D01AC4B24B49FC0A9DEE866669D9 /* SnackbarController.swift */, - 5C4C6087871B4325FCACD7729BCC7142 /* StatusBarController.swift */, - 48C8DD3ADA21FEC1C19ADACF1DA4DEBD /* Switch.swift */, - 9818E677DDAF7ED27910C966923CABEB /* TabBar.swift */, - C3D946174F3E557CD4FC1132C6314EF9 /* TableView.swift */, - A4649840170D6AA34B847908C8F4A7BA /* TableViewCell.swift */, - 56C2CD4361B65A92AF0CD0726C46C22C /* TableViewController.swift */, - 9BCCE7C2B99E6EAF7C935B30D8099848 /* TextField.swift */, - 4478B9BFEC84518FBF6BA118C1E6CB12 /* TextStorage.swift */, - 238367CB9EE1D75CA44120096771C5FC /* TextView.swift */, - 613B5985B4FAAAE96C41D1FA839C9831 /* Toolbar.swift */, - F4790179B22BE39130F0A994A92A4F2D /* ToolbarController.swift */, - F6039EE99F67816635C75BE125A56BF2 /* View.swift */, - EA2E1F4D92DB67A6C23E39EF9B17F87F /* Resources */, - ); - name = Core; - sourceTree = ""; - }; - 3F487F8E7D57C49C818CBABD9C157338 /* Classes */ = { - isa = PBXGroup; - children = ( - F92385CDBFE17EE69610B27067AC7FCE /* KeyboardSpy.swift */, - 8DDDCB0C43CADB19A98F4338101C1168 /* KeyboardSpyAgent.swift */, - D04E0FAEA80A394C9A0A29DF0BC13409 /* KeyboardSpyEvent.swift */, - 1B68143D947DEF19A7E8AA56B37B7CF9 /* KeyboardSpyInfo.swift */, - ); - path = Classes; + name = KeyboardSpy; + path = ../..; sourceTree = ""; }; - 4A160FDA7E6A53F67AE8CFD0565BAD4F /* Development Pods */ = { + 528E93BBC541A0A42DE70D37245C8509 /* Support Files */ = { isa = PBXGroup; children = ( - C904BD51EF94052E96A3122E89E6EF6C /* KeyboardSpy */, + 9EFEA8D85BFC2CD4BE60F580567556A2 /* Info.plist */, + CB366C6E4CB22A702214AC19A28C3145 /* KeyboardSpy.modulemap */, + 2CEB59D9A8E5ACDAB622147C5DB59779 /* KeyboardSpy.xcconfig */, + 13348C98368E04FF1B5010D0FDE1AFDC /* KeyboardSpy-dummy.m */, + DC9176A07A09F160CAEFC9731FB3E9B5 /* KeyboardSpy-prefix.pch */, + 746C113ED7D893C564FB2212795C20A9 /* KeyboardSpy-umbrella.h */, ); - name = "Development Pods"; + name = "Support Files"; + path = "Example/Pods/Target Support Files/KeyboardSpy"; sourceTree = ""; }; - 52FF970CCD3E5A1AC6536EC7B3A78159 /* Support Files */ = { + 5F372532E8397AC5CAFF514EFCD5B736 /* Pods */ = { isa = PBXGroup; children = ( - ECDFDEA96FCE7CAF30D9B87FBF15F7D2 /* Info.plist */, - D8B8102C24675A4EAA37F43B5F41CE68 /* Material.modulemap */, - 93D28BF617451FBF9A50EF928B8C6D75 /* Material.xcconfig */, - 3630DB0B6881F7C6F6F5AB4DBC566B0E /* Material-dummy.m */, - 793F6341BA6DD3253704E907314468D1 /* Material-prefix.pch */, - 7B07B9C2E705FFD7BBF4A7E5A0183CBE /* Material-umbrella.h */, - D2731D6D3B684A540BE1BD3AC680272A /* ResourceBundle-io.cosmicmind.material.fonts-Info.plist */, - DDA8FD3FB1F7D42831F715F9F26C61E5 /* ResourceBundle-io.cosmicmind.material.icons-Info.plist */, + C5BFEF3760A6CDCD45D4BA1B9682B079 /* Material */, + AFA699580BDC913D7B1676A6A9A8FFA9 /* SnapKit */, ); - name = "Support Files"; - path = "../Target Support Files/Material"; + name = Pods; sourceTree = ""; }; - 567E709B553C4A21B5E28A9E69882855 /* Support Files */ = { + 602331A6011B6ECCAD35C476FB71D299 /* Resources */ = { isa = PBXGroup; children = ( - 3BD648A25F73C4812338D3CC67A16113 /* Info.plist */, - 4431DCFCBEA896DEC8366BA082ED2692 /* KeyboardSpy.modulemap */, - CA9FF9A7B6D98C503DCB035D4E4B9833 /* KeyboardSpy.xcconfig */, - 8FD66C72073ECAA2B4FE8D6303DE29D1 /* KeyboardSpy-dummy.m */, - C4F9036CDCA9314E9334D6B4ACB7B1BD /* KeyboardSpy-prefix.pch */, - ED97A6BBA65BBA334E662ECA9E02B06E /* KeyboardSpy-umbrella.h */, + 35127700E6E1FD5733A6BB805095905A /* Assets.xcassets */, + 12D24C71A37F797ED7281CFE66DEB8ED /* Roboto-Bold.ttf */, + D5C87256138351F320508FE53BD4C7BB /* Roboto-Light.ttf */, + E56D6440BE5F3B60407251179CAD03A3 /* Roboto-Medium.ttf */, + 59FD9FB5A3AD6E1E2456A1E9B770AD18 /* Roboto-Regular.ttf */, + 59FD8B4965A0D2142072455B539D3A3B /* Roboto-Thin.ttf */, ); - name = "Support Files"; - path = "Example/Pods/Target Support Files/KeyboardSpy"; + name = Resources; sourceTree = ""; }; - 5EBFB92D348420D996250143FA81B971 /* Pods */ = { + 67605FFE76A11CB2E442273C907AB2A1 /* Development Pods */ = { isa = PBXGroup; children = ( - FCD61458AC6DB07A756F46406CBDC5DA /* Material */, - FA83EA80047A27686FFC6AC69A76631F /* SnapKit */, + 503FF2E1070BAB93E1A9254A7553B2C1 /* KeyboardSpy */, ); - name = Pods; + name = "Development Pods"; sourceTree = ""; }; 7DB346D0F39D3F0E887471402A8071AB = { isa = PBXGroup; children = ( 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */, - 4A160FDA7E6A53F67AE8CFD0565BAD4F /* Development Pods */, + 67605FFE76A11CB2E442273C907AB2A1 /* Development Pods */, BC3CA7F9E30CC8F7E2DD044DD34432FC /* Frameworks */, - 5EBFB92D348420D996250143FA81B971 /* Pods */, - AAA83FD9980B506BFCC754570B284864 /* Products */, + 5F372532E8397AC5CAFF514EFCD5B736 /* Pods */, + BB48000D6E3B33FBF2B3095FE438B8A1 /* Products */, EEED4E73F1C3DE7A52F0E7DD103ECE77 /* Targets Support Files */, ); sourceTree = ""; }; - A4CB1F85B6F851119323F089633DA0FB /* KeyboardSpy */ = { + AFA699580BDC913D7B1676A6A9A8FFA9 /* SnapKit */ = { isa = PBXGroup; children = ( - 3F487F8E7D57C49C818CBABD9C157338 /* Classes */, + 3CA3D8AF992D96CE94963FF1839EEBFB /* Constraint.swift */, + 96D9601403ED520105BF0F34E0F63125 /* ConstraintAttributes.swift */, + 0C223604E639DF5ADA18E089ECE32979 /* ConstraintConfig.swift */, + BF8D02890D88B7DD533215654556DF09 /* ConstraintConstantTarget.swift */, + C54DC92432F36790BD880DD997A13397 /* ConstraintDescription.swift */, + 15FD1EFE0D3328228965408D9F9FDE04 /* ConstraintDSL.swift */, + 82CC1F32060AEA7B22314F7F315C765C /* ConstraintInsets.swift */, + 0D28F26EE7BBED72FE444C2E2E378C65 /* ConstraintInsetTarget.swift */, + 5D080E614C5165DFBED6BFAACECE1CCB /* ConstraintItem.swift */, + 4FE148A95C46F92A3BC9823F7A1C2D83 /* ConstraintLayoutGuide.swift */, + 4B7223A3519C06913B81B56CB2A3A39D /* ConstraintLayoutGuide+Extensions.swift */, + E3E8770F8014FD52A4063DDCBF99F3AF /* ConstraintLayoutGuideDSL.swift */, + 6FE94E6DE0E4563E476761744B199D4F /* ConstraintLayoutSupport.swift */, + 8655037FB101023F644AB93D46531E3B /* ConstraintLayoutSupportDSL.swift */, + B5FC610D3C48E59F922BB216202B7B42 /* ConstraintMaker.swift */, + DB89BE5CF96047F5BB17B37983B6D44F /* ConstraintMakerEditable.swift */, + 984BDCC45A221413BAE5828C619531AD /* ConstraintMakerExtendable.swift */, + 50C6E544D13AF514C77C14D5637E6FB8 /* ConstraintMakerFinalizable.swift */, + A999BD3B694EF67F9145508F09E45B95 /* ConstraintMakerPriortizable.swift */, + 898E73CD666E0111686A18C887582A52 /* ConstraintMakerRelatable.swift */, + 6C1C187FD8952ED399F7B5EC47D4AA9C /* ConstraintMultiplierTarget.swift */, + 55C850B0B5A8873EDC66B9853309D9D9 /* ConstraintOffsetTarget.swift */, + 7CE5C53A344F86A38A3791DFD39984A0 /* ConstraintPriority.swift */, + 4B1A517903796A6981BAE5E931900276 /* ConstraintPriorityTarget.swift */, + 5C611A36A6E9F1AC68597DA589384EFD /* ConstraintRelatableTarget.swift */, + CE11A03BFD1F047DF81CE5D8DB7255A7 /* ConstraintRelation.swift */, + 162C40AA5CFEF7B409B405C3B381CA5E /* ConstraintView.swift */, + DD1440E42271BB98ED919BE226C8C8A7 /* ConstraintView+Extensions.swift */, + AEC428ECD599B5F5E5D6366D3D812BE8 /* ConstraintViewDSL.swift */, + EB02DAC86275C42724DEAE2F9FE4E176 /* Debugging.swift */, + 17264F50AD3297E8101D3773EA1CDD10 /* LayoutConstraint.swift */, + E82E40F4B23B27C90916581A7B4092DF /* LayoutConstraintItem.swift */, + 217562B7ED2569ADDAAA68BFDA380FC4 /* Typealiases.swift */, + C8B031678B3CB8D481599EACA7794892 /* UILayoutSupport+Extensions.swift */, + EA6547EE61F0CF65D2AE008799EC25FB /* Support Files */, ); - path = KeyboardSpy; + path = SnapKit; sourceTree = ""; }; - AAA83FD9980B506BFCC754570B284864 /* Products */ = { + BB48000D6E3B33FBF2B3095FE438B8A1 /* Products */ = { isa = PBXGroup; children = ( - 1B67B1C6393B5561FD27F0BACC14C642 /* io.cosmicmind.material.fonts.bundle */, - 74D407BF89192F7B53EBC558741601A2 /* io.cosmicmind.material.icons.bundle */, - 3EA7E84D555B4C827992F84B7CE5F2CD /* KeyboardSpy.framework */, - 32674C09DDF5A4B00A014DB05099CBB6 /* Material.framework */, - 627BC7E8A032AB69B428B18D377C8D3A /* Pods_KeyboardSpy_Example.framework */, - 497F6485F7A980F83AAB2472EF61D4DA /* SnapKit.framework */, + 89E26B785FD84FC8ED6D7769EC994673 /* com.cosmicmind.material.fonts.bundle */, + C49A43F3F33E4F98D64440EEBA7CAF31 /* com.cosmicmind.material.icons.bundle */, + B3D1DD856F87114CC8EB82FC2F806085 /* KeyboardSpy.framework */, + 3C221EEAAAE0F1EE0BD1DD752D7DE13D /* Material.framework */, + 4A2AF3355A6B5F0EEE97C8A3ECAD9302 /* Pods_KeyboardSpy_Example.framework */, + 336FBB6A87EDE9D9196BC57EA2101FD1 /* SnapKit.framework */, ); name = Products; sourceTree = ""; }; - B8C3D9D6A672DBED3C116D8E01FADD5F /* Support Files */ = { + BC3CA7F9E30CC8F7E2DD044DD34432FC /* Frameworks */ = { isa = PBXGroup; children = ( - 64BA1C116C3994F81B5F80A6E2018179 /* Info.plist */, - 18629F95148CC79833990FCD8C931D46 /* SnapKit.modulemap */, - 2358315198A7C0E84C8A34438C6360D5 /* SnapKit.xcconfig */, - 6922CFF6AB5A3AEB9320BC6491C95F06 /* SnapKit-dummy.m */, - AEB86F4BEDAB8E00CC260345E812888F /* SnapKit-prefix.pch */, - 828D6C8E170FA51D2D89BFEDD3C464F9 /* SnapKit-umbrella.h */, + D35AF013A5F0BAD4F32504907A52519E /* iOS */, ); - name = "Support Files"; - path = "../Target Support Files/SnapKit"; + name = Frameworks; sourceTree = ""; }; - BC3CA7F9E30CC8F7E2DD044DD34432FC /* Frameworks */ = { + C5BFEF3760A6CDCD45D4BA1B9682B079 /* Material */ = { isa = PBXGroup; children = ( - 3DCAB2B7CDE207B3958B6CB957FCC758 /* iOS */, + FDD803909DA83C63B34C4B0428FCD90A /* Core */, + CD4068A5640CECC07629B2A9FB5FB6BF /* Support Files */, ); - name = Frameworks; + path = Material; sourceTree = ""; }; - C904BD51EF94052E96A3122E89E6EF6C /* KeyboardSpy */ = { + CD4068A5640CECC07629B2A9FB5FB6BF /* Support Files */ = { isa = PBXGroup; children = ( - A4CB1F85B6F851119323F089633DA0FB /* KeyboardSpy */, - 567E709B553C4A21B5E28A9E69882855 /* Support Files */, + 512BDB7A758DDE4EE03731CCAB38EA6A /* Info.plist */, + 10A0D7EA5610BE39E9FB3DCF7850EA46 /* Material.modulemap */, + 7554641F0543351CC1138CD54CA8EE01 /* Material.xcconfig */, + F1C686E4EAE28D0BE02E823A6B18FB81 /* Material-dummy.m */, + EE1E7A093AB064438C67A655C6046BE2 /* Material-prefix.pch */, + 0070AC44FD24B99EE52892DF1AD1F220 /* Material-umbrella.h */, + 483F5A2415D80218DBFD1FEB15DC3E02 /* ResourceBundle-com.cosmicmind.material.fonts-Info.plist */, + 5E61179943BBB611A1033CC48D39D0AC /* ResourceBundle-com.cosmicmind.material.icons-Info.plist */, ); - name = KeyboardSpy; - path = ../..; + name = "Support Files"; + path = "../Target Support Files/Material"; sourceTree = ""; }; - EA2E1F4D92DB67A6C23E39EF9B17F87F /* Resources */ = { + D35AF013A5F0BAD4F32504907A52519E /* iOS */ = { isa = PBXGroup; children = ( - C8C4D638529F47D744014C0A1ACFD2B8 /* Assets.xcassets */, - 61CACCAFC625386A3516D06CE236C4BB /* Roboto-Bold.ttf */, - F6EFF83DEE934EA35FEDB304725A8F99 /* Roboto-Light.ttf */, - 137CA1F1B10E4EC527FD79DA09B9A232 /* Roboto-Medium.ttf */, - AA4DA8C856465AF25613B8DE31FA29F9 /* Roboto-Regular.ttf */, - D8083DE096D06A9A9755F0A0620AB65A /* Roboto-Thin.ttf */, + 6604A7D69453B4569E4E4827FB9155A9 /* Foundation.framework */, ); - name = Resources; + name = iOS; sourceTree = ""; }; - EEED4E73F1C3DE7A52F0E7DD103ECE77 /* Targets Support Files */ = { + EA6547EE61F0CF65D2AE008799EC25FB /* Support Files */ = { isa = PBXGroup; children = ( - 29618878F5D49F515FECF773D47E8DC5 /* Pods-KeyboardSpy_Example */, + 018E7026FF729DB32184167466D959AF /* Info.plist */, + E775BC5710D5B314EEEB3F6863B2554B /* SnapKit.modulemap */, + 481F5B635615A26BA7F541FD8C4B3458 /* SnapKit.xcconfig */, + 4693FC54E08F8CC0F4649066F0000071 /* SnapKit-dummy.m */, + 43EA7643013C12817DADAE6A56D144DA /* SnapKit-prefix.pch */, + 2CE1FF341717F3DC7D7B063D6B0A0A86 /* SnapKit-umbrella.h */, ); - name = "Targets Support Files"; + name = "Support Files"; + path = "../Target Support Files/SnapKit"; sourceTree = ""; }; - FA83EA80047A27686FFC6AC69A76631F /* SnapKit */ = { + EEED4E73F1C3DE7A52F0E7DD103ECE77 /* Targets Support Files */ = { isa = PBXGroup; children = ( - 59286B46714772F8B5110C675CA9E4E5 /* Constraint.swift */, - 8E0C2ECC32318E612A2616E4508C446C /* ConstraintAttributes.swift */, - E69D706A31179C60D704A37D72E084CB /* ConstraintConfig.swift */, - 8574BF3D0680E8B3FF01479BC6E6030B /* ConstraintConstantTarget.swift */, - 76CDE54CBC0B523EFDE97856F05EA6CD /* ConstraintDescription.swift */, - CF8F89D38616DD8F9464D1E50D9B6FA2 /* ConstraintDSL.swift */, - 18E13B7190D852B4061B2763D342560E /* ConstraintInsets.swift */, - 7CF05888635DDB2556D5E540E1348DE2 /* ConstraintInsetTarget.swift */, - C109BCAE67952558B9CA8F092EA9A567 /* ConstraintItem.swift */, - 1508FE4D19F51D57ABD80E4E5DA55A6E /* ConstraintLayoutGuide.swift */, - A3602387B591F81169705905D0F11DFC /* ConstraintLayoutGuide+Extensions.swift */, - 489E7C29FB18995359DF56C6CD587D22 /* ConstraintLayoutGuideDSL.swift */, - 10440FE2C155F716F5B22EAF2558CFD2 /* ConstraintLayoutSupport.swift */, - CD409C9F625BE16AA14A0059481BC570 /* ConstraintLayoutSupportDSL.swift */, - F40232B8523F1EA8697CBB582CA1F105 /* ConstraintMaker.swift */, - 259DD8B4DFDF095A59C643D55C855D5B /* ConstraintMakerEditable.swift */, - 6C4D4BD2840EA90650FE252BB9693AE9 /* ConstraintMakerExtendable.swift */, - 50C3D1709D201AB8633D3379DA9EB61D /* ConstraintMakerFinalizable.swift */, - 3A5E663832EA5319A80F4B865A728BDE /* ConstraintMakerPriortizable.swift */, - 279BD983E3CB70058E72691E62FAB246 /* ConstraintMakerRelatable.swift */, - C6CCDA7C0486BEA2F243119352DFAC83 /* ConstraintMultiplierTarget.swift */, - A50ABC396DD22F4FFF7DEC63DA7E7C0F /* ConstraintOffsetTarget.swift */, - 85315320E60D2D52CC7EAEBBC21463A6 /* ConstraintPriorityTarget.swift */, - 288B4F9DD6FF27B43CD7529C06ED68DA /* ConstraintRelatableTarget.swift */, - 998AD3233A9E4B030C240E4EA3323378 /* ConstraintRelation.swift */, - 1B08961DD7BA7CD3CED1C08692C90DDA /* ConstraintView.swift */, - 5986E6DD7BC1F388CC2A4C4A3E90482C /* ConstraintView+Extensions.swift */, - 0F3D602E6FBCE343A9F449D13208571B /* ConstraintViewDSL.swift */, - E22BF5FC7BE90AB43E1CBA18E2376C02 /* Debugging.swift */, - 308A0B595DF71E47E4D305564E1639E3 /* LayoutConstraint.swift */, - 55296E0F08CC0C7F4232ED6333949D70 /* LayoutConstraintItem.swift */, - 46E85FD2A85A33D289BA7F89A35422AD /* UILayoutSupport+Extensions.swift */, - B8C3D9D6A672DBED3C116D8E01FADD5F /* Support Files */, + 29618878F5D49F515FECF773D47E8DC5 /* Pods-KeyboardSpy_Example */, ); - path = SnapKit; + name = "Targets Support Files"; sourceTree = ""; }; - FCD61458AC6DB07A756F46406CBDC5DA /* Material */ = { + FDD803909DA83C63B34C4B0428FCD90A /* Core */ = { isa = PBXGroup; children = ( - 3DF463463D5F25F45A00CCA128ACFFD3 /* Core */, - 52FF970CCD3E5A1AC6536EC7B3A78159 /* Support Files */, + EFE796CA3ECFC814DDF9D7EB147F9924 /* Application.swift */, + 03412EF3A7A9D5489314B7F6FAF17EB4 /* Bar.swift */, + 1A8B9E37554D126D24D44B9611A779F2 /* Border.swift */, + 4CF77ADF624A2A645718F20F388FF409 /* BottomNavigationController.swift */, + 802641A5CF1A76C57D3BB9B8ACFC012F /* Button.swift */, + 789F24D8EB68E2D2479D47439BF3FFA1 /* Card.swift */, + A98FA3A05CCC692F52ADFBC6D639731F /* CardCollectionViewCell.swift */, + 950728AD99C523FE9AC4AF021A912D98 /* CardCollectionViewController.swift */, + 724F8483EBF2FD26F4D41D63F64B2220 /* CascadePreprocessor.swift */, + 8BFDD5A0A8B86B89D8E34AD0D5E89885 /* CharacterAttribute.swift */, + C3B704A01CFF273B6E6817C31A201649 /* ChipBar.swift */, + 4A081494ECAF4DF9F69FD642B5E83605 /* ChipBarController.swift */, + 79553E00CC72D70AFF8BB193101579E2 /* CollectionReusableView.swift */, + FE42BE25C4F00855A05A62C8BE5AF0A3 /* CollectionView.swift */, + D3A35CC89BE0B3799F6CC1D2AD20AEC3 /* CollectionViewCell.swift */, + 60259A0DAF13057DAC54F362932F7E52 /* CollectionViewController.swift */, + 3D81F6D5952A9F3A463C70D2BCF43E73 /* CollectionViewLayout.swift */, + 66BAB4D25B723308397559B82DC7B545 /* Color.swift */, + 8AD0C47E4179535B7CA07A252718D02B /* CornerRadius.swift */, + C0833A6504E0C528A274EE2E3695DE5B /* DataSourceItem.swift */, + 9A9479DAE0B452979DFBF59758339AE2 /* Depth.swift */, + A6663232B21A072859EDE9347DEA9C07 /* Device.swift */, + CFFD8A5A2C59A73F737A1845C022FA12 /* DisplayStyle.swift */, + 6F779C0647CC8D560F8253FCC53F4CB7 /* Divider.swift */, + 081A85D61ACC638F8C4609BF0D074707 /* DurationPreprocessor.swift */, + 7F8B3AECB2CE612A01D32F93F28018A0 /* DynamicFontType.swift */, + EFD6D0315D42263212698DD1E325BC26 /* EdgeInsets.swift */, + 997E15A2B422B6F94889B04D865E0D1D /* ErrorTextField.swift */, + 5B0B36A7CE96D869B7ACBBB2EBDA905F /* FABButton.swift */, + C4FE4756F341027C2CA36BFB29AD3FED /* FABMenu.swift */, + FF064103CED8717386EE459CA9A3FBFB /* FABMenuController.swift */, + 46A628B86F7E8DFD403412AD66BD0DC1 /* FlatButton.swift */, + 063C827D23F6C30673679EF4962B80BA /* Font.swift */, + C807F9DBF420871936843B8A0FC1736E /* Gravity.swift */, + C3D6B71FE7158E9A18B8BC31D2A0C0C3 /* Grid.swift */, + 4D67D847A76445CFABB19330480C5729 /* HeightPreset.swift */, + 7A4303A2BEA3726D0E5E09F049E7353E /* Icon.swift */, + 7BF349907A54AB4AB35912BB4297D237 /* IconButton.swift */, + 088E77384B11B6E45BE9A26EAA99DA25 /* IgnoreSubviewModifiersPreprocessor.swift */, + 4A57C4B1BD27B48F524414DBD6A9AC1C /* ImageCard.swift */, + 9FBDADDBB78E63A6F8F536C1A8A1BF6C /* InterimSpace.swift */, + 91356D8E95C500958415574ED91CF53C /* Layer.swift */, + B1D14CD0FA0EA6589A755F5E831231F9 /* Layout.swift */, + CBAC8A27D3958D51129ADE237A6BB871 /* MatchPreprocessor.swift */, + 96C22AFB26EE0F5060AC4A1773505C2A /* Material+Array.swift */, + A795AFA4EFBE1DC0CDF4312824621FCB /* Material+CALayer.swift */, + BB04C0C99C8D6CF1DE9805D6EB74578D /* Material+MotionAnimation.swift */, + 9DDA18D5E5704B28AE964CB185FB2F81 /* Material+String.swift */, + 7E09CD729CD53ECADE86C5CAA46AFEA2 /* Material+UIFont.swift */, + 15B1DB147338653CC41B55270365A70D /* Material+UIImage.swift */, + D012601CD0E44779C7B38BACB100B084 /* Material+UIView.swift */, + 916E6656F4A77EDA6ACF9C11736B9520 /* Material+UIViewController.swift */, + 53693D841B2B8BCD50FC5A5EB1A7C254 /* Material+UIWindow.swift */, + 58C29E8BB6FFFBF28CD92D380CAE0968 /* Motion.swift */, + 8F88EF8CD7E5ECCD9A2AE3D934B4B2A1 /* Motion+Array.swift */, + B79769A1E065BEE70DED915FB67360BA /* Motion+CALayer.swift */, + C82088279A7BAC2ACA71BD231A794B45 /* Motion+CAMediaTimingFunction.swift */, + C7B2A2CEE688E7FBE29FB8C7C6C9C14C /* Motion+CG.swift */, + DF1EDDBFF8C329BD4F24163606F15863 /* Motion+Obj-C.swift */, + 36B37F159DFEF0BE9004762ECB656187 /* Motion+UIKit.swift */, + B17790D1A558455995AD12F9838E4AFE /* Motion+UIView.swift */, + E22CD3715683FC8F8421450810107AF5 /* Motion+UIViewController.swift */, + 499408A4B19535EBD30AEA2EF4FB99C5 /* MotionAnimation.swift */, + 74CF9573521287109B626947CE07DFF4 /* MotionAnimationFillMode.swift */, + 487A400166FA22AD3E9B612510E7B7F1 /* MotionAnimationState.swift */, + A240F13043E832ED2C0DE4197F53986C /* MotionAnimator.swift */, + 333EC9315BA04B42207F035F62305FEB /* MotionAnimatorViewContext.swift */, + E1A932A7AB1D47B56E9F950843DD50C1 /* MotionCAAnimation.swift */, + 5B6003FCCEBCB8E473887B41D4DCB25B /* MotionContext.swift */, + CC2A7794E9A8E4BF593E8BEA3CC13F9A /* MotionController.swift */, + FD4A4E8CE120E15B55290A847452C225 /* MotionCoordinateSpace.swift */, + 90914AE4D3F87A0BDB6083372A492EDF /* MotionCoreAnimationViewContext.swift */, + 8BE935A6FC3B6BDA73FC5D76069040CB /* MotionHasInsertOrder.swift */, + 7E6BD2E15F44CC91A2451ACC85A5CF9A /* MotionIndependentController.swift */, + 5C6FCC5CDB1D913BD264CDB67C86F4F4 /* MotionPlugin.swift */, + 0160981436DACD22BEAB0879E24620A7 /* MotionPreprocessor.swift */, + 338FE444D8BAFEBC0759FD9F96748DC7 /* MotionSnapshotType.swift */, + F33DF18C8CC85F9333323B05E2BCFDBC /* MotionTransition.swift */, + 7C8884F6E1A3577084D069711AFA8A3D /* MotionTransitionAnimator.swift */, + BB514EB93F1D1F059B49B8382FEBD7EF /* MotionTransitionObserver.swift */, + 1A3C0F320BA6193469A5EA85A4506036 /* MotionTransitionState.swift */, + 032BE899369FCD6BA85FD0ACC035AF01 /* MotionViewPropertyViewContext.swift */, + 5067B551F58C6CBAF02AACA2588B3A2E /* NavigationBar.swift */, + 341D52075E4B522176783D1F09D77CBB /* NavigationController.swift */, + 9E33F9931AA03B2C728FF889D2CA2835 /* NavigationDrawerController.swift */, + 82EB798C1FB4D9EEA1F592220008F4DF /* NavigationItem.swift */, + B2EC919E0280AFAFAB77B12431195872 /* Offset.swift */, + 9A5E3544BD773E033215450E9F0FBFD5 /* PresenterCard.swift */, + 66AA832FAEC662DFE2E79B120597DB97 /* PulseAnimation.swift */, + F66BF21C7F9438187C912CF65A4F61B8 /* PulseView.swift */, + 5A42AE8FC34C0BFCEB2CC540BF41F869 /* RaisedButton.swift */, + 2814A42589427CEA42ECAFF272BF53C8 /* RobotoFont.swift */, + 820338254434C6CB3C9C9ECC0D575906 /* Screen.swift */, + 27105484605742DDCC8DE41C54728AE7 /* SearchBar.swift */, + 5B962828A6BE66FBF013FB6CBC6C0376 /* SearchBarController.swift */, + F147E88F444EB0CC44F735B0844EC33F /* Shape.swift */, + 8223A33C2D47D3C1DBC9D3AB5C7C0CDD /* Snackbar.swift */, + 744F73221AAB025C438C3CD405A68D67 /* SnackbarController.swift */, + 248A4B01BB125D3E899952287A81ABAE /* SourcePreprocessor.swift */, + D574C53286086E5ADCBC3B2172BB541D /* SpringAnimation.swift */, + 5B407895836E5055B827DDF5582B2F5E /* StatusBarController.swift */, + 1485669703D7EF2F432F23BFFBCF1FF7 /* Switch.swift */, + D27978F3C1B67B34E354A66CA7A4F3E1 /* TabBar.swift */, + 2ACB20CA2B272DAC4B439935F1759B2E /* TableView.swift */, + 8B21646206535ACA03016E06B41E7D2B /* TableViewCell.swift */, + 1A351C83FF2E10ADA2917C6931D73817 /* TableViewController.swift */, + 7738D28DAE703698826FF9FC7C9AB092 /* TabsController.swift */, + C61EE6C02AE9902C041D6D8B3D67D533 /* TextField.swift */, + 43DA5D78DA585F03E7335F023388071C /* TextStorage.swift */, + 62AA6DA8DD31877CCBED3B41BAE939C3 /* TextView.swift */, + 48270BDDE59DE398D04189141411D1AE /* Toolbar.swift */, + 16DA0155646F03DCF6DEF433BD7062F2 /* ToolbarController.swift */, + 803EC022B8A7FF20442F8462F128CC47 /* TransitionController.swift */, + A49A02172E372515A37DFB2B609B718F /* TransitionPreprocessor.swift */, + 562520D21C313BC739ADA36597DE7B37 /* View.swift */, + 602331A6011B6ECCAD35C476FB71D299 /* Resources */, ); - path = Material; + name = Core; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ - 09E46341F280BC78C760F57BB1D20F1B /* Headers */ = { + 4F3AF705BF458D2C9B08392B5968EE90 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 51989B46FE335C57B129AC49DC8D83E3 /* SnapKit-umbrella.h in Headers */, + E17C9E65E4105A57A08030B32154AB13 /* Material-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - 81528FD49CAEDE2D0BDD9C2B8C604976 /* Headers */ = { + 69733E5393499983143C2AB0FC6215ED /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 9B60BE7632D171F35D1540E89712E000 /* Material-umbrella.h in Headers */, + E2255C1CF40161E107499A05C05E4535 /* KeyboardSpy-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - E52175B90E8B9205DAE3592796D4E2C6 /* Headers */ = { + D0299891801E1C199564E419F466BBDA /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 68419532AB36559889B118BFDD80B96C /* Pods-KeyboardSpy_Example-umbrella.h in Headers */, + 77B1926F11AC1B1249D03D61B9BA05DB /* SnapKit-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; - FE0C2A1D8509592C3D327A7909854186 /* Headers */ = { + D61963E377531EBB1B607E0E2D51A5F5 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 6C2FCFBDD0E47AAEE9D846821463A9F5 /* KeyboardSpy-umbrella.h in Headers */, + 4CB67C61304D12CF7300825288C75E8F /* Pods-KeyboardSpy_Example-umbrella.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ - 0FB771E0DE35ABAFDF00C9CA54493BDD /* Material */ = { + 2D6B45908ECC3888F51EC4CF7298F759 /* Material-com.cosmicmind.material.fonts */ = { isa = PBXNativeTarget; - buildConfigurationList = 7572C734E6D15D83A761186A58F31EC1 /* Build configuration list for PBXNativeTarget "Material" */; + buildConfigurationList = DBEC2A429EC4BD015E9DA3E5475949FA /* Build configuration list for PBXNativeTarget "Material-com.cosmicmind.material.fonts" */; buildPhases = ( - D7694285C262A7DCADC84A954B549BD0 /* Sources */, - C1C9095E3C364CD535400E1417934B0D /* Frameworks */, - 4925144C40283083C199583B7CB355F7 /* Resources */, - 81528FD49CAEDE2D0BDD9C2B8C604976 /* Headers */, + 3DD49DDF982CF552A12D83A152B80C62 /* Sources */, + 7D866B8D4F4E2D07C95C784AA706D0A1 /* Frameworks */, + 21C32B53E11F9590F39D20646D887F67 /* Resources */, ); buildRules = ( ); dependencies = ( - 8F04102C18D91FFBE8C8CE54CD9762D3 /* PBXTargetDependency */, - 91D05A5A26F94CD6F6A71F37EB58E926 /* PBXTargetDependency */, ); - name = Material; - productName = Material; - productReference = 32674C09DDF5A4B00A014DB05099CBB6 /* Material.framework */; - productType = "com.apple.product-type.framework"; + name = "Material-com.cosmicmind.material.fonts"; + productName = "Material-com.cosmicmind.material.fonts"; + productReference = 89E26B785FD84FC8ED6D7769EC994673 /* com.cosmicmind.material.fonts.bundle */; + productType = "com.apple.product-type.bundle"; }; - 36D7B55B95E6A1236AEF513E8FD9238E /* KeyboardSpy */ = { + 415640AE1BAB89361F9D757D666EB139 /* Material */ = { isa = PBXNativeTarget; - buildConfigurationList = 6B689F1D2637204C5FC3120CB308971B /* Build configuration list for PBXNativeTarget "KeyboardSpy" */; + buildConfigurationList = 5C6E1D771FA6432D71AD35919B82145F /* Build configuration list for PBXNativeTarget "Material" */; buildPhases = ( - 4FF4647108459323C4F4B78D9340C937 /* Sources */, - CC4987E463FF6FAD2A219B76D3D32069 /* Frameworks */, - FE0C2A1D8509592C3D327A7909854186 /* Headers */, + C08DFAF2843B5E18CA8B89B76EE3E584 /* Sources */, + 6E9307AB48EFF5D40659A36A82396C2E /* Frameworks */, + 48B64EF749D300FD66B53E44E2CD5DCC /* Resources */, + 4F3AF705BF458D2C9B08392B5968EE90 /* Headers */, ); buildRules = ( ); dependencies = ( + 6538D7FC86D0E20A25F2FD3BFC379BA3 /* PBXTargetDependency */, + 8EE11867871245C2C69C04C8BE5D6C17 /* PBXTargetDependency */, ); - name = KeyboardSpy; - productName = KeyboardSpy; - productReference = 3EA7E84D555B4C827992F84B7CE5F2CD /* KeyboardSpy.framework */; + name = Material; + productName = Material; + productReference = 3C221EEAAAE0F1EE0BD1DD752D7DE13D /* Material.framework */; productType = "com.apple.product-type.framework"; }; - 4A3AED5BAF9E9AF799FE28CFB72FE3F7 /* Material-io.cosmicmind.material.fonts */ = { + 4CBC8DD3CD3F13C4EF87425DF5B8AC9A /* Material-com.cosmicmind.material.icons */ = { isa = PBXNativeTarget; - buildConfigurationList = 081B26DF50C1EE013AD15C1C4B40F25B /* Build configuration list for PBXNativeTarget "Material-io.cosmicmind.material.fonts" */; + buildConfigurationList = 66CCA8D119CF3BBA6337F797504BA1C2 /* Build configuration list for PBXNativeTarget "Material-com.cosmicmind.material.icons" */; buildPhases = ( - 264E2AC20EF438F0FD3279170420C39D /* Sources */, - 026C5E63E1CE6543E4FAAA53B0829C84 /* Frameworks */, - 1BA95FFF46E379F231E6DA12DC4FEC26 /* Resources */, + C032C11378BD0E306D9D37617BAF9377 /* Sources */, + C856AA90E251A11ADCA37EA2D4A83E90 /* Frameworks */, + 37B7D61BA9AA54BBF4BA3DADA4C8040E /* Resources */, ); buildRules = ( ); dependencies = ( ); - name = "Material-io.cosmicmind.material.fonts"; - productName = "Material-io.cosmicmind.material.fonts"; - productReference = 1B67B1C6393B5561FD27F0BACC14C642 /* io.cosmicmind.material.fonts.bundle */; + name = "Material-com.cosmicmind.material.icons"; + productName = "Material-com.cosmicmind.material.icons"; + productReference = C49A43F3F33E4F98D64440EEBA7CAF31 /* com.cosmicmind.material.icons.bundle */; productType = "com.apple.product-type.bundle"; }; - 63F8092C414A0508CAF3FCF21C6409EA /* Pods-KeyboardSpy_Example */ = { + 8303ECB6B90CFF1D24DA6ADA7CAFD334 /* KeyboardSpy */ = { isa = PBXNativeTarget; - buildConfigurationList = EC857555EFFF091E2E28D65D1B3046EF /* Build configuration list for PBXNativeTarget "Pods-KeyboardSpy_Example" */; + buildConfigurationList = F6233B77EAE4FF06285D36C1A9B98162 /* Build configuration list for PBXNativeTarget "KeyboardSpy" */; buildPhases = ( - 762F0F007627DBA99D43225CA792C6EC /* Sources */, - 0847FA7176FA5F8A726CA1BC356543E9 /* Frameworks */, - E52175B90E8B9205DAE3592796D4E2C6 /* Headers */, + 27A508B074858ABE4811AFDF60B2CA45 /* Sources */, + FA2ABA9162802D388565A7DD88ED44D4 /* Frameworks */, + 69733E5393499983143C2AB0FC6215ED /* Headers */, ); buildRules = ( ); dependencies = ( - 903F2655A9DF3F533FE2AD502BD77BE5 /* PBXTargetDependency */, - 33380654A600030AA56F5BA6D8F136C2 /* PBXTargetDependency */, - 855C6224F55866C0FCCCDF7A71EFDCB1 /* PBXTargetDependency */, ); - name = "Pods-KeyboardSpy_Example"; - productName = "Pods-KeyboardSpy_Example"; - productReference = 627BC7E8A032AB69B428B18D377C8D3A /* Pods_KeyboardSpy_Example.framework */; + name = KeyboardSpy; + productName = KeyboardSpy; + productReference = B3D1DD856F87114CC8EB82FC2F806085 /* KeyboardSpy.framework */; productType = "com.apple.product-type.framework"; }; - E6EDA33F2979D1FBE905B02DD311590D /* SnapKit */ = { + 9A7B3FB64E7B250083D638DAA82A1180 /* SnapKit */ = { isa = PBXNativeTarget; - buildConfigurationList = 3D7F11829ED5933F16300642C5A2DB13 /* Build configuration list for PBXNativeTarget "SnapKit" */; + buildConfigurationList = 5B164B009509A756D78BE1F1E51A9758 /* Build configuration list for PBXNativeTarget "SnapKit" */; buildPhases = ( - 4F1BDE0C833D558050E15526E22FBFDB /* Sources */, - E259225F6411EF111405F5F6E6CE0BE9 /* Frameworks */, - 09E46341F280BC78C760F57BB1D20F1B /* Headers */, + 57ADB10BEDC37AE02309EEE417326C01 /* Sources */, + F7298E1CBF7FC5C57D86A36136D48625 /* Frameworks */, + D0299891801E1C199564E419F466BBDA /* Headers */, ); buildRules = ( ); @@ -835,25 +921,28 @@ ); name = SnapKit; productName = SnapKit; - productReference = 497F6485F7A980F83AAB2472EF61D4DA /* SnapKit.framework */; + productReference = 336FBB6A87EDE9D9196BC57EA2101FD1 /* SnapKit.framework */; productType = "com.apple.product-type.framework"; }; - EE23AC8CFA049B54594921CED4E38996 /* Material-io.cosmicmind.material.icons */ = { + CDB39E047719DC86BA20BED5650F578F /* Pods-KeyboardSpy_Example */ = { isa = PBXNativeTarget; - buildConfigurationList = 6914D1DF3634FF531BFE0A02DBCB94D8 /* Build configuration list for PBXNativeTarget "Material-io.cosmicmind.material.icons" */; + buildConfigurationList = 05D1845C66659234F1740725FF639201 /* Build configuration list for PBXNativeTarget "Pods-KeyboardSpy_Example" */; buildPhases = ( - C3A1AF3055B86D76E8E5EB674E206726 /* Sources */, - 69DF737A5588C675242D141CC39C2362 /* Frameworks */, - E07963DDB3D010BB63050356BFBE3064 /* Resources */, + 307A34A8472972872E365639DCF6F267 /* Sources */, + 3B857261449ACF71DBA28CAED042C611 /* Frameworks */, + D61963E377531EBB1B607E0E2D51A5F5 /* Headers */, ); buildRules = ( ); dependencies = ( + D34656B4765F3814EF152EDAE1D3D967 /* PBXTargetDependency */, + C1A2CA6B654688ECDC30F1D3F9CDA9A9 /* PBXTargetDependency */, + 15DCF0FC3B9CFA34D16E03C5015ACF4A /* PBXTargetDependency */, ); - name = "Material-io.cosmicmind.material.icons"; - productName = "Material-io.cosmicmind.material.icons"; - productReference = 74D407BF89192F7B53EBC558741601A2 /* io.cosmicmind.material.icons.bundle */; - productType = "com.apple.product-type.bundle"; + name = "Pods-KeyboardSpy_Example"; + productName = "Pods-KeyboardSpy_Example"; + productReference = 4A2AF3355A6B5F0EEE97C8A3ECAD9302 /* Pods_KeyboardSpy_Example.framework */; + productType = "com.apple.product-type.framework"; }; /* End PBXNativeTarget section */ @@ -861,8 +950,8 @@ D41D8CD98F00B204E9800998ECF8427E /* Project object */ = { isa = PBXProject; attributes = { - LastSwiftUpdateCheck = 0730; - LastUpgradeCheck = 0700; + LastSwiftUpdateCheck = 0830; + LastUpgradeCheck = 0900; }; buildConfigurationList = 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */; compatibilityVersion = "Xcode 3.2"; @@ -872,623 +961,650 @@ en, ); mainGroup = 7DB346D0F39D3F0E887471402A8071AB; - productRefGroup = AAA83FD9980B506BFCC754570B284864 /* Products */; + productRefGroup = BB48000D6E3B33FBF2B3095FE438B8A1 /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( - 36D7B55B95E6A1236AEF513E8FD9238E /* KeyboardSpy */, - 0FB771E0DE35ABAFDF00C9CA54493BDD /* Material */, - 4A3AED5BAF9E9AF799FE28CFB72FE3F7 /* Material-io.cosmicmind.material.fonts */, - EE23AC8CFA049B54594921CED4E38996 /* Material-io.cosmicmind.material.icons */, - 63F8092C414A0508CAF3FCF21C6409EA /* Pods-KeyboardSpy_Example */, - E6EDA33F2979D1FBE905B02DD311590D /* SnapKit */, + 8303ECB6B90CFF1D24DA6ADA7CAFD334 /* KeyboardSpy */, + 415640AE1BAB89361F9D757D666EB139 /* Material */, + 2D6B45908ECC3888F51EC4CF7298F759 /* Material-com.cosmicmind.material.fonts */, + 4CBC8DD3CD3F13C4EF87425DF5B8AC9A /* Material-com.cosmicmind.material.icons */, + CDB39E047719DC86BA20BED5650F578F /* Pods-KeyboardSpy_Example */, + 9A7B3FB64E7B250083D638DAA82A1180 /* SnapKit */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ - 1BA95FFF46E379F231E6DA12DC4FEC26 /* Resources */ = { + 21C32B53E11F9590F39D20646D887F67 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 9797093A4EEE7DCCC9D6D48FC1898EA9 /* Roboto-Bold.ttf in Resources */, - A4AE628C99F3127A27CA0A169F2F7A43 /* Roboto-Light.ttf in Resources */, - 041F8818FE29EDD798F46469BC138C3C /* Roboto-Medium.ttf in Resources */, - 72C2032BEC3F1EFA654FF30C31527AA0 /* Roboto-Regular.ttf in Resources */, - AB57F92568F8E8645C122BF5083A92A7 /* Roboto-Thin.ttf in Resources */, + 682DBA88A140AA358F42615D531809E8 /* Roboto-Bold.ttf in Resources */, + 0BEBBAEABB39A6147908D63B347F8C42 /* Roboto-Light.ttf in Resources */, + 01D646C3E8FD950788639235EA734EB6 /* Roboto-Medium.ttf in Resources */, + B02DAF3AC652A417CC799301CAFF0027 /* Roboto-Regular.ttf in Resources */, + 66AF531C017FC9C06138060F169F69E0 /* Roboto-Thin.ttf in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 4925144C40283083C199583B7CB355F7 /* Resources */ = { + 37B7D61BA9AA54BBF4BA3DADA4C8040E /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - D47CD82DD6BE1BC1356BAB24C63B74E5 /* io.cosmicmind.material.fonts.bundle in Resources */, - 5ED4F621B9D375DF822FCEB9365DBE52 /* io.cosmicmind.material.icons.bundle in Resources */, + 49E8BC64A0A6FF0A908E7A9BE8A12C5A /* Assets.xcassets in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; - E07963DDB3D010BB63050356BFBE3064 /* Resources */ = { + 48B64EF749D300FD66B53E44E2CD5DCC /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - C1CF8CF79BD77976B4F10953DF811D79 /* Assets.xcassets in Resources */, + 4A61E4ED9BE9286A8EDF83FBD6CF1AE8 /* com.cosmicmind.material.fonts.bundle in Resources */, + 07EBAF3B5177C769228CC46A54758F8E /* com.cosmicmind.material.icons.bundle in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ - 264E2AC20EF438F0FD3279170420C39D /* Sources */ = { + 27A508B074858ABE4811AFDF60B2CA45 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 20BF1A4181DEFD602769EC9EB238A123 /* KeyboardSpy-dummy.m in Sources */, + C549768BABBED1C32593ADDF2AB24272 /* KeyboardSpy.swift in Sources */, + 9F46AEDFD7CC94A04723B5F2CB5614EA /* KeyboardSpyAgent.swift in Sources */, + F6C7244470E241EDE3B63FF86C13F807 /* KeyboardSpyEvent.swift in Sources */, + 033C8F83710056A4119206425F8300AA /* KeyboardSpyInfo.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 4F1BDE0C833D558050E15526E22FBFDB /* Sources */ = { + 307A34A8472972872E365639DCF6F267 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 038467314E74EFFBD0F8B9D99296E12A /* Constraint.swift in Sources */, - 332C00ED864DAC5BA34505EB45011F6E /* ConstraintAttributes.swift in Sources */, - AB209D3AA85A8C3D56C6A3E059606E20 /* ConstraintConfig.swift in Sources */, - 03950C59BF61B33174F4FAE0F3B78C9F /* ConstraintConstantTarget.swift in Sources */, - D0140346362CA3DE42F0A6BED2D33664 /* ConstraintDescription.swift in Sources */, - A56A138292D79B686457C4E52E5D50A2 /* ConstraintDSL.swift in Sources */, - 8031C583A16B689B88139C80BF56347C /* ConstraintInsets.swift in Sources */, - 8F33FD9490104035547A7050074C539A /* ConstraintInsetTarget.swift in Sources */, - 8C8DD9463410992FAD7B9C5D5641AD4A /* ConstraintItem.swift in Sources */, - 8926B75526F4140341D9ED25A9BA741B /* ConstraintLayoutGuide+Extensions.swift in Sources */, - 80345CB832ECC3486C17FBE5407E9E02 /* ConstraintLayoutGuide.swift in Sources */, - 2A470A43222FD9C00E182536F74EC789 /* ConstraintLayoutGuideDSL.swift in Sources */, - 7DC011757098CD63CA38FBA776DA1A33 /* ConstraintLayoutSupport.swift in Sources */, - F13B12ED9BC99BBC146D594DC60EEAD9 /* ConstraintLayoutSupportDSL.swift in Sources */, - 848F4E74AA194356983ECC45D0B91F61 /* ConstraintMaker.swift in Sources */, - E7C3384668CFDBC09EE99EF44BE4D1FB /* ConstraintMakerEditable.swift in Sources */, - 088B9975A92495DD9C802A5B3EFCC0E2 /* ConstraintMakerExtendable.swift in Sources */, - 5AE8CD3647945C891F5197673BD262AD /* ConstraintMakerFinalizable.swift in Sources */, - AE18B38EA5587A04AA5AFF5916E8B3F7 /* ConstraintMakerPriortizable.swift in Sources */, - 3FE2F4127830858BD8FB0E021AAC652F /* ConstraintMakerRelatable.swift in Sources */, - C520A8827546636A7AE9EE622A20171B /* ConstraintMultiplierTarget.swift in Sources */, - A97198F52DC71E2A2C0FF2074A9A3844 /* ConstraintOffsetTarget.swift in Sources */, - 8F84A963BFBD63C6E8D0E05E1E53C9BB /* ConstraintPriorityTarget.swift in Sources */, - D297FDD36FE5963B5EAB5C48D33B5225 /* ConstraintRelatableTarget.swift in Sources */, - 74B88CD3CC07EEF0B1E70A800E210EE5 /* ConstraintRelation.swift in Sources */, - 9D1E16ED4552065F8C20B8F370FEF202 /* ConstraintView+Extensions.swift in Sources */, - E12EDE20910982BCECD89DC073B2E144 /* ConstraintView.swift in Sources */, - 71B5753CFF85DE929604D8DB75472F3F /* ConstraintViewDSL.swift in Sources */, - 53964849233A438AD05FF49D49786EFA /* Debugging.swift in Sources */, - 5A30ED864F3C7FF840DB2816EC67BDC4 /* LayoutConstraint.swift in Sources */, - 56ACC73D8791BD63CEB2D8EF746C1369 /* LayoutConstraintItem.swift in Sources */, - A5B9441BC6ACB47C57C40FEDBBC777C0 /* SnapKit-dummy.m in Sources */, - 9796F7CBA480722539E4BAE0074817F6 /* UILayoutSupport+Extensions.swift in Sources */, + 76F4139461A827C32772CB47A2032B75 /* Pods-KeyboardSpy_Example-dummy.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 4FF4647108459323C4F4B78D9340C937 /* Sources */ = { + 3DD49DDF982CF552A12D83A152B80C62 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - BCFD6C12E707FA2385780888B375AC97 /* KeyboardSpy-dummy.m in Sources */, - 430407820477E1EBA2EC0F4D1B7B558C /* KeyboardSpy.swift in Sources */, - 393A6FD40BF13F3F3657200EFF1546BF /* KeyboardSpyAgent.swift in Sources */, - 314720DDFBEB9586D0E78230356D18C0 /* KeyboardSpyEvent.swift in Sources */, - 4045091ABC321CDD36B299EBB874CC55 /* KeyboardSpyInfo.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 762F0F007627DBA99D43225CA792C6EC /* Sources */ = { + 57ADB10BEDC37AE02309EEE417326C01 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - BBC23616DAA0BFC1872463EA7FCE8E39 /* Pods-KeyboardSpy_Example-dummy.m in Sources */, + 8B4FDB372E2E397AB249F66454F5040C /* Constraint.swift in Sources */, + F56133A1A940BCBB47502861EFAE7DC4 /* ConstraintAttributes.swift in Sources */, + E575C81FA77C27D00412B7B6A099FE33 /* ConstraintConfig.swift in Sources */, + 005E87111AB718E3EADDDADD7FF51E0C /* ConstraintConstantTarget.swift in Sources */, + 9ADB674635B12AE658E36BC199D96666 /* ConstraintDescription.swift in Sources */, + BCCDA4E282F640D8F1B027116C795157 /* ConstraintDSL.swift in Sources */, + 2992AC9140BEDA92B62389EA5B36BD37 /* ConstraintInsets.swift in Sources */, + 4B13ECE4D13EF648F8788A7CEDD6FF06 /* ConstraintInsetTarget.swift in Sources */, + ACF7533531EB81FB89FB8A1E2D9743FE /* ConstraintItem.swift in Sources */, + 863459EDE07FABCB88A17DD90FE122F2 /* ConstraintLayoutGuide+Extensions.swift in Sources */, + 2230958798AC58DDDB871BAA740824BA /* ConstraintLayoutGuide.swift in Sources */, + 69825A74C86113E8BFFFDD990A1B4483 /* ConstraintLayoutGuideDSL.swift in Sources */, + 5986374897FB6600354E426C637F11DD /* ConstraintLayoutSupport.swift in Sources */, + 6C37A2568A764B378F940094FAF64BAE /* ConstraintLayoutSupportDSL.swift in Sources */, + 8583A7495E2057773C740E07C62F50D3 /* ConstraintMaker.swift in Sources */, + 971992D40047BD9904BFD2C2594D2AE3 /* ConstraintMakerEditable.swift in Sources */, + 032F0DC686D2F3DB159B913B3992ACE0 /* ConstraintMakerExtendable.swift in Sources */, + 1D61F6D01EE9B908F67B7A275FF254E6 /* ConstraintMakerFinalizable.swift in Sources */, + 011304F6B7F86A0473E05C896B9A07D6 /* ConstraintMakerPriortizable.swift in Sources */, + CF48B55B39379054482C3EC80E0EEB72 /* ConstraintMakerRelatable.swift in Sources */, + FBCD752E37B53A1F0C028EDC25841E12 /* ConstraintMultiplierTarget.swift in Sources */, + 1B2A577EE2C3BC38D98B74B383529776 /* ConstraintOffsetTarget.swift in Sources */, + 9E8303279366A81AB681258A0F8A2DD5 /* ConstraintPriority.swift in Sources */, + 203BF03E16E8F3395C05839B6469FC31 /* ConstraintPriorityTarget.swift in Sources */, + A974074BAACE59E199D98A7E6A0D309D /* ConstraintRelatableTarget.swift in Sources */, + 228BD9DBB45F0DF8EE5743650D62A1B7 /* ConstraintRelation.swift in Sources */, + 6BAFDE4F917DA65F7A7CEDBA8FDB11A4 /* ConstraintView+Extensions.swift in Sources */, + 1A2D832730D6CB1FE7F9EA08DD6CCEDD /* ConstraintView.swift in Sources */, + ADB27961B4F26F93C16FA889A96DA792 /* ConstraintViewDSL.swift in Sources */, + BA98FC1793725CE258FDE198B3EF3B7B /* Debugging.swift in Sources */, + F63725D70FFAEDA45E74FCFA16DCCD2E /* LayoutConstraint.swift in Sources */, + EDAB5E7454C3C2EC5E9C7E4C7EDDE3D8 /* LayoutConstraintItem.swift in Sources */, + 6DE54531EA11A594E853A02F28521680 /* SnapKit-dummy.m in Sources */, + D5084D8FD090947A72843A62721868C4 /* Typealiases.swift in Sources */, + 374552759F369E2F17B795AB2E88638E /* UILayoutSupport+Extensions.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - C3A1AF3055B86D76E8E5EB674E206726 /* Sources */ = { + C032C11378BD0E306D9D37617BAF9377 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - D7694285C262A7DCADC84A954B549BD0 /* Sources */ = { + C08DFAF2843B5E18CA8B89B76EE3E584 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 9305975DE58297B119B274A978637993 /* Application.swift in Sources */, - C2CBDEA1FF82DB8BA8086FB40D5FFA4D /* Bar.swift in Sources */, - E2B2CFCC2D3768220CF9F7335D08B257 /* Border.swift in Sources */, - F4E0B84BC56D3800BF8CFB436090B442 /* BottomNavigationController.swift in Sources */, - 67764772F5E84D50BDE210ADB104149A /* BottomTabBar.swift in Sources */, - 6E072E60B6F0DE01692443973D67F2C1 /* Button.swift in Sources */, - 4A7F4710D5CC3DD0493A9789B19A44DB /* Card.swift in Sources */, - 5BF08BFB86CDB5F9ED72D0BF7726EA5F /* CharacterAttribute.swift in Sources */, - 7CA24CCEAB7688344297266563B6D7B4 /* CollectionReusableView.swift in Sources */, - CAA7BDFA7CFCAD5629BDECF1B739414D /* CollectionView.swift in Sources */, - FF99F14EBD759D3AE46D76F4CE6EE874 /* CollectionViewCell.swift in Sources */, - 97DCC37E37AC37C980C06F20938E9D58 /* CollectionViewController.swift in Sources */, - E4CA1ACD52102C3397B3301E624B7650 /* CollectionViewLayout.swift in Sources */, - 29EDEA7E8B7BABEE31ED9614AC458A88 /* Color.swift in Sources */, - 3A764EE000FA63AAE897B536AF1B1355 /* CornerRadius.swift in Sources */, - FD234321E262A3B7C19A640D01ADE015 /* DataSourceItem.swift in Sources */, - 108BFFCF9DE940FE68A1462EC3B4EC89 /* Depth.swift in Sources */, - 57B38166C0C692A75708F2A8AE8E6823 /* Device.swift in Sources */, - EBB704A8ADFB51196A98206041486256 /* Display.swift in Sources */, - E31EB4B8B34D52B85629B1C064C9D433 /* Divider.swift in Sources */, - 1104FB451F79B05DE6F604BB9A263A44 /* DynamicFontType.swift in Sources */, - 82DA1092C729308791BAC34352B0DB08 /* EdgeInsets.swift in Sources */, - C790BFB952FE9D68025179219065B6F7 /* Editor.swift in Sources */, - 9245C8B1E62B500F0DCDF3EF8FE7D20B /* EditorController.swift in Sources */, - 54A631C19A6E4F9A9E75C0EA7938F5B5 /* ErrorTextField.swift in Sources */, - 1603A4DF011F122D27EFF7AE88B3F1B2 /* FabButton.swift in Sources */, - 408DF434D98C7D0C0B3272F32FD889D4 /* FlatButton.swift in Sources */, - E937898D95469D07EF42711A5B700137 /* Font.swift in Sources */, - DA23706870F3BCA0BEDD872481AB7457 /* Gravity.swift in Sources */, - 7D624CC1D3D79DA69676897F08166084 /* Grid.swift in Sources */, - 1F29B801935B0201E36B4837FC8FA309 /* HeightPreset.swift in Sources */, - 74BE458E2740DA78698557408BD571A4 /* Icon.swift in Sources */, - 478926EE4EA225BA4D77B57501BAD3DA /* IconButton.swift in Sources */, - 042A341D388FDD4A6F1ED5BC37520FB6 /* ImageCard.swift in Sources */, - B263CDA6B9D65BC7488E1A9AC0F53389 /* InterimSpace.swift in Sources */, - 62AAA0508EC605D8C0B4CC86BAB2C100 /* Layer.swift in Sources */, - 58AB7BD193C92C789799EB5453F226D9 /* Layout.swift in Sources */, - 68DD16A5D31384E22C087BBDCA40845F /* Material+Array.swift in Sources */, - A5EE2C2012D918D6AC99A4E89346043D /* Material+CALayer.swift in Sources */, - 90FCFA82AFEAB745E65376964BA7F620 /* Material+Obj-C.swift in Sources */, - C49587EA956AC9B1DB87CCF7448625FA /* Material+String.swift in Sources */, - 68CF79C3AA1EBB59BBFF7426B1102DF1 /* Material+UIFont.swift in Sources */, - EF8EC0245532B6E955344A548E737E51 /* Material+UIImage.swift in Sources */, - 9D63C1072186D5B5AA06E90DA1B4E92A /* Material+UIView.swift in Sources */, - 596214455316ECE5C1446C8B9D54455F /* Material+UIWindow.swift in Sources */, - FBBA6EE0DBADFBD0865D9D65EE760D13 /* Material-dummy.m in Sources */, - AE0D36ED18BD1E056022ED3364665273 /* Menu.swift in Sources */, - F0EF73A649E917771D288D49038530A2 /* MenuController.swift in Sources */, - 085D8569FC69B36C65045B42D8C04908 /* MenuItem.swift in Sources */, - FCB163F72D772F3EF6946C6D7D5F7099 /* Motion.swift in Sources */, - 8722A0209A541CC726618E59BB5E4067 /* MotionBasic.swift in Sources */, - 4EEE4120445D44C7578CCDB7978930E8 /* MotionKeyframe.swift in Sources */, - CC6C627BB67CCED726C16A4DED0D5291 /* MotionPulse.swift in Sources */, - 0E87C93AA24D9B5867D2A76BD6B106DD /* MotionTransition.swift in Sources */, - 31A868B795032F24CE7E4EA25129FF93 /* NavigationBar.swift in Sources */, - E288EE18D790F1895E206097030551FF /* NavigationController.swift in Sources */, - 732CE59AC540554CE13017B7A2AE441A /* NavigationDrawerController.swift in Sources */, - F55E7BC534A3CD2559EA76F11514BC69 /* NavigationItem.swift in Sources */, - 4370380B3DAF72486223D4899A6AD6B4 /* Offset.swift in Sources */, - 64424B8E644C619D74842BC52CB6E6C6 /* PageTabBarController.swift in Sources */, - 0EF2BF49EA6B91EFBBF3C1D8E0DA8EB2 /* PresenterCard.swift in Sources */, - 71D84D2CFBD83BFB145F0695ED657868 /* PulseView.swift in Sources */, - C80AFA937D98F7CFC405F634C5F305EF /* RaisedButton.swift in Sources */, - 161B9A182D426280DEB4A857A1A30643 /* RobotoFont.swift in Sources */, - 3BA70F07F971E6F9BCCDFA64596D8976 /* RootController.swift in Sources */, - 696EBEE205A2F204DCC8A62ADF79A205 /* Screen.swift in Sources */, - E7FCE040010DDFCC1C46D70CA417EA1A /* SearchBar.swift in Sources */, - 927C84FADB96E6280467637648A1301C /* SearchBarController.swift in Sources */, - 3B8CDD6DB935E882F4D7E4C5B0797D84 /* Shape.swift in Sources */, - 681BDC2A3825785488941AA42D9145BA /* Snackbar.swift in Sources */, - 96FDB81A962C446F1FDCCC3598645322 /* SnackbarController.swift in Sources */, - 441CB6FD9F500D2F85A2880DF46B0F0D /* StatusBarController.swift in Sources */, - 3D290D86B2D4375A97D90B366146374E /* Switch.swift in Sources */, - 719B3731A3CD3640B2006248EFD9845A /* TabBar.swift in Sources */, - A73B0852B9086FECBD180497B8442170 /* TableView.swift in Sources */, - AF7EBD7DCE6327D16205B22FD19103FF /* TableViewCell.swift in Sources */, - 2C1349BD5B9128E6ED7F74A2F9EBBBE9 /* TableViewController.swift in Sources */, - 1A2712A32F25B1C2AAFB6A11A93E8D8A /* TextField.swift in Sources */, - 82E350FFDE42493FB116C516939E8DAF /* TextStorage.swift in Sources */, - 3C3A89CC4080B7A8541997E42004AE74 /* TextView.swift in Sources */, - 748C19F532E69EA4343DF40D451B8C1B /* Toolbar.swift in Sources */, - D354A63F813200D89CBCDCE13FE5BE5D /* ToolbarController.swift in Sources */, - 03496A5A4D098F402532B3083CF1C635 /* View.swift in Sources */, + 8FFB51B8411191E2B387524032776803 /* Application.swift in Sources */, + C721A5E19F7B107EF497F74A9A675D56 /* Bar.swift in Sources */, + 6F2DFA6333E6DA36AC571A475B167C56 /* Border.swift in Sources */, + D456FA51D80D980FCD917E93FF9CF563 /* BottomNavigationController.swift in Sources */, + F3714079FE1F8010C452157B4E330364 /* Button.swift in Sources */, + A8D63483ABE5D98359765BAB2CB0CB6E /* Card.swift in Sources */, + 9DC23DC52665A9ECE2E7CAA4B8E5AB03 /* CardCollectionViewCell.swift in Sources */, + F87C7079ABD93A491569C22E28EA550B /* CardCollectionViewController.swift in Sources */, + D4F0037004B942FAD150FEF023EE357F /* CascadePreprocessor.swift in Sources */, + 317A9E558F109B19FE85C84C616FB8AF /* CharacterAttribute.swift in Sources */, + 4D6AB54D0B5BD084A267F46A5CA694C3 /* ChipBar.swift in Sources */, + B2209FF6A03930DDE4171C07FBFE26F6 /* ChipBarController.swift in Sources */, + 349826FE47DC5FAAB50B0CB57B7C2178 /* CollectionReusableView.swift in Sources */, + 829484505F896CEA0E759C6613FCBEE3 /* CollectionView.swift in Sources */, + ABB1D6F06BCCF17E8BC732BC0811ACD4 /* CollectionViewCell.swift in Sources */, + 5D072CAC30B46DFE2BE3448C5937E490 /* CollectionViewController.swift in Sources */, + 59F3195723100D08A25D37E169C26D98 /* CollectionViewLayout.swift in Sources */, + 6775E0A854154AEC0F7F4B264BAB95EB /* Color.swift in Sources */, + 2870E48B34F083B16C2C959BD75FC404 /* CornerRadius.swift in Sources */, + 98EEFDF381873F6F122D7F6D2072B840 /* DataSourceItem.swift in Sources */, + 30EB799982F19E3D13B9C8DAAFB2A1BB /* Depth.swift in Sources */, + 71E255C4A6F65EA8965346B4F71C9C2E /* Device.swift in Sources */, + ECF0BA2807CDCB6295DE031A4E24BF3B /* DisplayStyle.swift in Sources */, + 27F0539777960A6FFC6CBF9295673211 /* Divider.swift in Sources */, + 42267446E84AA4DB7DCBC444B38246EB /* DurationPreprocessor.swift in Sources */, + 21F51E59AED8D78FC74F1E232F8143AD /* DynamicFontType.swift in Sources */, + BAF3320D8CEE07BAF7D6F7DE561214E1 /* EdgeInsets.swift in Sources */, + 7BA206A0830E9E19358856A7C0B762E2 /* ErrorTextField.swift in Sources */, + 3283FAC62680D4B28E2F1BF9CD7CFC02 /* FABButton.swift in Sources */, + 78B44D65414EE139DDF167A2B0A00365 /* FABMenu.swift in Sources */, + 7A2DC0502FE0A40266D6DCA2850A1EE1 /* FABMenuController.swift in Sources */, + 4349F1775A2166C4E17D59BC58158811 /* FlatButton.swift in Sources */, + 60F9587E2995FCBD2D9E4F7D96518547 /* Font.swift in Sources */, + FC8392B60F1FC8DDAB3719C1FDFE424E /* Gravity.swift in Sources */, + 38EED7F068EFBF80B0F16D9E52247925 /* Grid.swift in Sources */, + 9D33D752F8F1D789262767240753046A /* HeightPreset.swift in Sources */, + C8B332AAC8BF202036A7123E69F715BF /* Icon.swift in Sources */, + 5787FE13473CA22BF235F75AECD773EB /* IconButton.swift in Sources */, + 2C977BA53D3D660B16282C57913CF0EF /* IgnoreSubviewModifiersPreprocessor.swift in Sources */, + 44DD0A4E583407C658DCEC76C9B9BE64 /* ImageCard.swift in Sources */, + B943391BE943BE0F0AACC18D84748275 /* InterimSpace.swift in Sources */, + 7605F9C36D2E99FBD8EC41B93F13AC2E /* Layer.swift in Sources */, + F6B20D0B4582D2160277122EC163BFA4 /* Layout.swift in Sources */, + E6923B5D55C1AC8D8A8AC198D8932759 /* MatchPreprocessor.swift in Sources */, + A760C777574AB7762F4395432369B080 /* Material+Array.swift in Sources */, + 25763D4DD43396719BB473D52FB4A800 /* Material+CALayer.swift in Sources */, + 72AA010724B4D03C95DE306EEA951F58 /* Material+MotionAnimation.swift in Sources */, + 3E2306C0DD8E78A5D4F4E1201466FDDA /* Material+String.swift in Sources */, + 98947C919BFCC23F72CEFC99254384B3 /* Material+UIFont.swift in Sources */, + 233CAD6E0D37779BF56D2C16E07C2A89 /* Material+UIImage.swift in Sources */, + FA57F7B06160B7831AF602F195228F65 /* Material+UIView.swift in Sources */, + 0EC8AEC224B2F0A586A8D9C4ADCC54CE /* Material+UIViewController.swift in Sources */, + 7EFE33398572E74E2C571216EFEC61A2 /* Material+UIWindow.swift in Sources */, + F8B666DB156DA86ADACC879FF0A141B2 /* Material-dummy.m in Sources */, + C3DA93801BE0BBC0152DD7CDB453B22A /* Motion+Array.swift in Sources */, + D6DCF082035B59E817006A1898B07A27 /* Motion+CALayer.swift in Sources */, + C9890F1484C54D5B0796FA51F968B48E /* Motion+CAMediaTimingFunction.swift in Sources */, + 18E5ECEF844279891489DAE4FF115124 /* Motion+CG.swift in Sources */, + 5DCDF6F753EFF0C71839E275D82BD246 /* Motion+Obj-C.swift in Sources */, + F3B72D5CF31DC5B25096C569FA9535F6 /* Motion+UIKit.swift in Sources */, + 0A8D5B9C6A790E3B60386D82B053B6FE /* Motion+UIView.swift in Sources */, + 430FDA33C0E2E53D1DEA6395C33CEDAE /* Motion+UIViewController.swift in Sources */, + F4321205AF2D78E63456231202EE3DDA /* Motion.swift in Sources */, + 5DCFA206F133DA1443C76380B6523229 /* MotionAnimation.swift in Sources */, + D98ADB2D5F898C7FC70747212BF98DF0 /* MotionAnimationFillMode.swift in Sources */, + C0D3D3CCC50F9EBCD10BF38B0C9B8A6B /* MotionAnimationState.swift in Sources */, + 618F2B4864EF2094F213F69D23CAFC86 /* MotionAnimator.swift in Sources */, + D99CDFFF1F63572EBE2D687E3737C25B /* MotionAnimatorViewContext.swift in Sources */, + 2D0971F0DCF71F5A2FBA6D18F4AF32F8 /* MotionCAAnimation.swift in Sources */, + 6D5715694A543CDC054984C92FD230F1 /* MotionContext.swift in Sources */, + 97AF3F674B6F7E81980C8BB0968283FD /* MotionController.swift in Sources */, + 3EFEE885BBAF6EAD5D1B2B2DB67EC416 /* MotionCoordinateSpace.swift in Sources */, + D519BF78DAD9D88A36801B6F8199D225 /* MotionCoreAnimationViewContext.swift in Sources */, + 52E5917269886C8174E68FB4DC2B47F0 /* MotionHasInsertOrder.swift in Sources */, + DA9A81098A23094833F7B6712566AC5C /* MotionIndependentController.swift in Sources */, + F0D5947F7BD5A430811FE042A1B68193 /* MotionPlugin.swift in Sources */, + 9B899B1FDFFAD41CCD315ABA89E96169 /* MotionPreprocessor.swift in Sources */, + 83346C7329B66DC89DD08399BB402822 /* MotionSnapshotType.swift in Sources */, + 72D1B052A4977B4D3D21544EFA65423D /* MotionTransition.swift in Sources */, + F298FF46E6C6B996C833F3CE6BEBFB2A /* MotionTransitionAnimator.swift in Sources */, + DB0ECB9132998626B268DEAACACF42DA /* MotionTransitionObserver.swift in Sources */, + E41D9398364755B9A7B25920F9BB5116 /* MotionTransitionState.swift in Sources */, + 5083A2E487712FED80A714BCA40691F5 /* MotionViewPropertyViewContext.swift in Sources */, + 0DC74D0FB022F1EA1EDFBBBFA62A1412 /* NavigationBar.swift in Sources */, + AF14FC0BEA2138DB66723C317301A27D /* NavigationController.swift in Sources */, + 7E388B5E14B39321B06A6E9CCDED0AE4 /* NavigationDrawerController.swift in Sources */, + 3B8BCA9C6ADEF4201B158DC3A6A04CB6 /* NavigationItem.swift in Sources */, + 9EC473D1895C30979CF1C5C92ADE0C46 /* Offset.swift in Sources */, + F66051524782B05A34F39EE51E290468 /* PresenterCard.swift in Sources */, + 631F2D66F64E306AEB2040F3CC4EECC3 /* PulseAnimation.swift in Sources */, + 00A36B3D82A970F771B949B095C5AA56 /* PulseView.swift in Sources */, + 6CB63AB35EDD699D46456ACE62D3BA2E /* RaisedButton.swift in Sources */, + 419F139EEF405DD6A546E0A8D623D144 /* RobotoFont.swift in Sources */, + 6988699AE65690D9A0F37F9AD7D9129C /* Screen.swift in Sources */, + A3B24C60F178A193C64F96D216E04A5A /* SearchBar.swift in Sources */, + 5475AA1F4BCEEC69D4A160C970E4940B /* SearchBarController.swift in Sources */, + DFD66F5101BFE82712C43DE9F607C659 /* Shape.swift in Sources */, + 42DB6F9CF427540EC6D8B2C665BF31AC /* Snackbar.swift in Sources */, + B686052BEEA72CEDED17B0B0D321D5EA /* SnackbarController.swift in Sources */, + 5E426DB8406EF0CA404F2FC29A79F8E9 /* SourcePreprocessor.swift in Sources */, + D31FECBF3A17A0A6857B29A5B74DB2B0 /* SpringAnimation.swift in Sources */, + E1A3E75068301E782D51D0ACCAFAE851 /* StatusBarController.swift in Sources */, + 0E35BEAA1C4F8D53B3AC5A5405AA005F /* Switch.swift in Sources */, + 340810A0CF44A31945F00057467C7AB1 /* TabBar.swift in Sources */, + 80AEAE02F3E1B75151CD5CB9FA66BE8A /* TableView.swift in Sources */, + 8428A9EA4C7D682AB7F80CCD36BED3BA /* TableViewCell.swift in Sources */, + 0B9C7FB837C6824A1A4BAA1DCEDA27ED /* TableViewController.swift in Sources */, + E6F376E7F49EF10B10A066B6F4E4F722 /* TabsController.swift in Sources */, + 0CEBA550622152219CDE78213C3A4450 /* TextField.swift in Sources */, + D982501E51CD6C09A377EF0173DAD361 /* TextStorage.swift in Sources */, + AB997A4BD3241FC9C29A3567F85C8DB9 /* TextView.swift in Sources */, + 3470380DA530E8815FAAF42E763CFDEC /* Toolbar.swift in Sources */, + 212CF544C11552D9B450542D4693E388 /* ToolbarController.swift in Sources */, + 0A34FFF35DD87698BDCD8CA4EAED377B /* TransitionController.swift in Sources */, + DFD93DEA5204068949EC80286A95E3FC /* TransitionPreprocessor.swift in Sources */, + B6F789A90051F2F7A0B8E977C9219AD8 /* View.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ - 33380654A600030AA56F5BA6D8F136C2 /* PBXTargetDependency */ = { + 15DCF0FC3B9CFA34D16E03C5015ACF4A /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = Material; - target = 0FB771E0DE35ABAFDF00C9CA54493BDD /* Material */; - targetProxy = 761E989276C2C0D088BC262BDAE666CD /* PBXContainerItemProxy */; + name = SnapKit; + target = 9A7B3FB64E7B250083D638DAA82A1180 /* SnapKit */; + targetProxy = 4AE3FE1948E04A0CDC1E7F1E24475F4D /* PBXContainerItemProxy */; }; - 855C6224F55866C0FCCCDF7A71EFDCB1 /* PBXTargetDependency */ = { + 6538D7FC86D0E20A25F2FD3BFC379BA3 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = SnapKit; - target = E6EDA33F2979D1FBE905B02DD311590D /* SnapKit */; - targetProxy = C54D1C6BA7F3CAD8CC67CC9AFD3ABACF /* PBXContainerItemProxy */; + name = "Material-com.cosmicmind.material.fonts"; + target = 2D6B45908ECC3888F51EC4CF7298F759 /* Material-com.cosmicmind.material.fonts */; + targetProxy = F6C7521CE7F1019BF4FC0FE999137331 /* PBXContainerItemProxy */; }; - 8F04102C18D91FFBE8C8CE54CD9762D3 /* PBXTargetDependency */ = { + 8EE11867871245C2C69C04C8BE5D6C17 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = "Material-io.cosmicmind.material.fonts"; - target = 4A3AED5BAF9E9AF799FE28CFB72FE3F7 /* Material-io.cosmicmind.material.fonts */; - targetProxy = 0B5A6F5E5F10490C703C97509E627E99 /* PBXContainerItemProxy */; + name = "Material-com.cosmicmind.material.icons"; + target = 4CBC8DD3CD3F13C4EF87425DF5B8AC9A /* Material-com.cosmicmind.material.icons */; + targetProxy = 391E40A3270DC79E4109B71526FB8311 /* PBXContainerItemProxy */; }; - 903F2655A9DF3F533FE2AD502BD77BE5 /* PBXTargetDependency */ = { + C1A2CA6B654688ECDC30F1D3F9CDA9A9 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = KeyboardSpy; - target = 36D7B55B95E6A1236AEF513E8FD9238E /* KeyboardSpy */; - targetProxy = 60210F77EA66C0C8280299D57726D095 /* PBXContainerItemProxy */; + name = Material; + target = 415640AE1BAB89361F9D757D666EB139 /* Material */; + targetProxy = 03ED6BFE2BFDFDCA0C6A4CFF8F0FA467 /* PBXContainerItemProxy */; }; - 91D05A5A26F94CD6F6A71F37EB58E926 /* PBXTargetDependency */ = { + D34656B4765F3814EF152EDAE1D3D967 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - name = "Material-io.cosmicmind.material.icons"; - target = EE23AC8CFA049B54594921CED4E38996 /* Material-io.cosmicmind.material.icons */; - targetProxy = 7A61A66BCC069B9EDB985046BEA0D122 /* PBXContainerItemProxy */; + name = KeyboardSpy; + target = 8303ECB6B90CFF1D24DA6ADA7CAFD334 /* KeyboardSpy */; + targetProxy = 3CF9B67E3D8F9FE4A4A3546D323744E5 /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ - 015A368F878AC3E2CEAE21DDE8026304 /* Debug */ = { + 10D9F733A96625C0A8711685F3CB62D1 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 7554641F0543351CC1138CD54CA8EE01 /* Material.xcconfig */; buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - 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; - CODE_SIGNING_REQUIRED = NO; - COPY_PHASE_STRIP = NO; - ENABLE_TESTABILITY = YES; - GCC_C_LANGUAGE_STANDARD = gnu99; - GCC_DYNAMIC_NO_PIC = NO; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "POD_CONFIGURATION_DEBUG=1", - "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; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Material"; + INFOPLIST_FILE = "Target Support Files/Material/ResourceBundle-com.cosmicmind.material.icons-Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; - ONLY_ACTIVE_ARCH = YES; - PROVISIONING_PROFILE_SPECIFIER = NO_SIGNING/; - STRIP_INSTALLED_PRODUCT = NO; - SYMROOT = "${SRCROOT}/../build"; + PRODUCT_NAME = com.cosmicmind.material.icons; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = bundle; }; - name = Debug; + name = Release; }; - 171EFA09ABFFF7688C68CE89FF09034C /* Debug */ = { + 151B439DDB7BCFCED56112004F112A82 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 2358315198A7C0E84C8A34438C6360D5 /* SnapKit.xcconfig */; + baseConfigurationReference = 2CEB59D9A8E5ACDAB622147C5DB59779 /* KeyboardSpy.xcconfig */; buildSettings = { + CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; CURRENT_PROJECT_VERSION = 1; - DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_NO_COMMON_BLOCKS = YES; - GCC_PREFIX_HEADER = "Target Support Files/SnapKit/SnapKit-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/SnapKit/Info.plist"; + GCC_PREFIX_HEADER = "Target Support Files/KeyboardSpy/KeyboardSpy-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/KeyboardSpy/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MODULEMAP_FILE = "Target Support Files/SnapKit/SnapKit.modulemap"; - MTL_ENABLE_DEBUG_INFO = YES; - PRODUCT_NAME = SnapKit; + MODULEMAP_FILE = "Target Support Files/KeyboardSpy/KeyboardSpy.modulemap"; + PRODUCT_NAME = KeyboardSpy; SDKROOT = iphoneos; SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 4.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Debug; }; - 24F77A7B9ED504305AF684746EF7682E /* Debug */ = { + 31F5410416803125010A991989C69DF8 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = CA9FF9A7B6D98C503DCB035D4E4B9833 /* KeyboardSpy.xcconfig */; + baseConfigurationReference = B3B937BCC6657E47A8E865D991C0864D /* Pods-KeyboardSpy_Example.debug.xcconfig */; buildSettings = { + CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; CURRENT_PROJECT_VERSION = 1; - DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_NO_COMMON_BLOCKS = YES; - GCC_PREFIX_HEADER = "Target Support Files/KeyboardSpy/KeyboardSpy-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/KeyboardSpy/Info.plist"; + INFOPLIST_FILE = "Target Support Files/Pods-KeyboardSpy_Example/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MODULEMAP_FILE = "Target Support Files/KeyboardSpy/KeyboardSpy.modulemap"; - MTL_ENABLE_DEBUG_INFO = YES; - PRODUCT_NAME = KeyboardSpy; + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-KeyboardSpy_Example/Pods-KeyboardSpy_Example.modulemap"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = Pods_KeyboardSpy_Example; SDKROOT = iphoneos; SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Debug; }; - 2944DC914CD83BCF8E0A9782B579811B /* Debug */ = { + 4364047A2AACCE76A784DEC3AC4205A2 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 93D28BF617451FBF9A50EF928B8C6D75 /* Material.xcconfig */; + baseConfigurationReference = 7554641F0543351CC1138CD54CA8EE01 /* Material.xcconfig */; buildSettings = { - CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Material"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_NO_COMMON_BLOCKS = YES; - INFOPLIST_FILE = "Target Support Files/Material/ResourceBundle-io.cosmicmind.material.icons-Info.plist"; + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/Material/Material-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/Material/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; - PRODUCT_NAME = io.cosmicmind.material.icons; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MODULEMAP_FILE = "Target Support Files/Material/Material.modulemap"; + PRODUCT_NAME = Material; SDKROOT = iphoneos; SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 3.2; TARGETED_DEVICE_FAMILY = "1,2"; - WRAPPER_EXTENSION = bundle; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; }; name = Debug; }; - 2CE5FF8B951893563CB1EAE81AB383AD /* Release */ = { + 4504FD64F19E45723C6B0EAEE5B01760 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 05B9FB8DAADA38B14AB68493C55221B9 /* Pods-KeyboardSpy_Example.release.xcconfig */; + baseConfigurationReference = 7554641F0543351CC1138CD54CA8EE01 /* Material.xcconfig */; buildSettings = { + CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; CURRENT_PROJECT_VERSION = 1; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_NO_COMMON_BLOCKS = YES; - INFOPLIST_FILE = "Target Support Files/Pods-KeyboardSpy_Example/Info.plist"; + GCC_PREFIX_HEADER = "Target Support Files/Material/Material-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/Material/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MACH_O_TYPE = staticlib; - MODULEMAP_FILE = "Target Support Files/Pods-KeyboardSpy_Example/Pods-KeyboardSpy_Example.modulemap"; - MTL_ENABLE_DEBUG_INFO = NO; - OTHER_LDFLAGS = ""; - OTHER_LIBTOOLFLAGS = ""; - PODS_ROOT = "$(SRCROOT)"; - PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; - PRODUCT_NAME = Pods_KeyboardSpy_Example; + MODULEMAP_FILE = "Target Support Files/Material/Material.modulemap"; + PRODUCT_NAME = Material; SDKROOT = iphoneos; SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 3.2; TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Release; }; - 349DEA4563438F92BD6EA1B0ABDBE6CE /* Release */ = { + 4F51CB0611652A7F6AAA0E9CDEC8F69F /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 2358315198A7C0E84C8A34438C6360D5 /* SnapKit.xcconfig */; + baseConfigurationReference = 481F5B635615A26BA7F541FD8C4B3458 /* SnapKit.xcconfig */; buildSettings = { + CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; CURRENT_PROJECT_VERSION = 1; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_NO_COMMON_BLOCKS = YES; GCC_PREFIX_HEADER = "Target Support Files/SnapKit/SnapKit-prefix.pch"; INFOPLIST_FILE = "Target Support Files/SnapKit/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MODULEMAP_FILE = "Target Support Files/SnapKit/SnapKit.modulemap"; - MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_NAME = SnapKit; SDKROOT = iphoneos; SKIP_INSTALL = YES; - SWIFT_VERSION = 3.0; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 4.0; TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Release; }; - 3685740571C1E35339DFB2B3B602ABF9 /* Release */ = { + 741C0CD69706CE66E451F2BFB4798265 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 93D28BF617451FBF9A50EF928B8C6D75 /* Material.xcconfig */; + baseConfigurationReference = 7554641F0543351CC1138CD54CA8EE01 /* Material.xcconfig */; buildSettings = { - "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; - "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; - CURRENT_PROJECT_VERSION = 1; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_NO_COMMON_BLOCKS = YES; - GCC_PREFIX_HEADER = "Target Support Files/Material/Material-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/Material/Info.plist"; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + CODE_SIGN_IDENTITY = "iPhone Developer"; + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Material"; + INFOPLIST_FILE = "Target Support Files/Material/ResourceBundle-com.cosmicmind.material.fonts-Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MODULEMAP_FILE = "Target Support Files/Material/Material.modulemap"; - MTL_ENABLE_DEBUG_INFO = NO; - PRODUCT_NAME = Material; + PRODUCT_NAME = com.cosmicmind.material.fonts; SDKROOT = iphoneos; SKIP_INSTALL = YES; - SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = "1,2"; - VERSIONING_SYSTEM = "apple-generic"; - VERSION_INFO_PREFIX = ""; + WRAPPER_EXTENSION = bundle; }; name = Release; }; - 44CDBB6D11DE06DB64D6268622BDC47E /* Release */ = { + A8F02BB0755E6AC927CCA374978E7D00 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7554641F0543351CC1138CD54CA8EE01 /* Material.xcconfig */; + buildSettings = { + CODE_SIGN_IDENTITY = "iPhone Developer"; + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Material"; + INFOPLIST_FILE = "Target Support Files/Material/ResourceBundle-com.cosmicmind.material.fonts-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + PRODUCT_NAME = com.cosmicmind.material.fonts; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = bundle; + }; + name = Debug; + }; + B0431A31FF973448A952FA06F2B8F4AE /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7554641F0543351CC1138CD54CA8EE01 /* Material.xcconfig */; + buildSettings = { + CODE_SIGN_IDENTITY = "iPhone Developer"; + CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Material"; + INFOPLIST_FILE = "Target Support Files/Material/ResourceBundle-com.cosmicmind.material.icons-Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + PRODUCT_NAME = com.cosmicmind.material.icons; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + WRAPPER_EXTENSION = bundle; + }; + name = Debug; + }; + B254DAA6CF0CE39F4A3D11B90A7E059A /* Release */ = { isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGNING_REQUIRED = NO; - COPY_PHASE_STRIP = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; - GCC_C_LANGUAGE_STANDARD = gnu99; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; GCC_PREPROCESSOR_DEFINITIONS = ( "POD_CONFIGURATION_RELEASE=1", "$(inherited)", ); GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.0; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = NO_SIGNING/; STRIP_INSTALLED_PRODUCT = NO; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; SYMROOT = "${SRCROOT}/../build"; - VALIDATE_PRODUCT = YES; }; name = Release; }; - 653C7D4641DD8E5A4AA1C3775DBBF5AF /* Debug */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 93D28BF617451FBF9A50EF928B8C6D75 /* Material.xcconfig */; - buildSettings = { - CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Material"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_NO_COMMON_BLOCKS = YES; - INFOPLIST_FILE = "Target Support Files/Material/ResourceBundle-io.cosmicmind.material.fonts-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - PRODUCT_NAME = io.cosmicmind.material.fonts; - SDKROOT = iphoneos; - SKIP_INSTALL = YES; - TARGETED_DEVICE_FAMILY = "1,2"; - WRAPPER_EXTENSION = bundle; - }; - name = Debug; - }; - 74AB2315FD8A8D88E8BA5C94CC03ACC5 /* Release */ = { + B3D5BC3778688A70E16D845CE924B1B1 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = CA9FF9A7B6D98C503DCB035D4E4B9833 /* KeyboardSpy.xcconfig */; + baseConfigurationReference = 2CEB59D9A8E5ACDAB622147C5DB59779 /* KeyboardSpy.xcconfig */; buildSettings = { + CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; CURRENT_PROJECT_VERSION = 1; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_NO_COMMON_BLOCKS = YES; GCC_PREFIX_HEADER = "Target Support Files/KeyboardSpy/KeyboardSpy-prefix.pch"; INFOPLIST_FILE = "Target Support Files/KeyboardSpy/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MODULEMAP_FILE = "Target Support Files/KeyboardSpy/KeyboardSpy.modulemap"; - MTL_ENABLE_DEBUG_INFO = NO; PRODUCT_NAME = KeyboardSpy; SDKROOT = iphoneos; SKIP_INSTALL = YES; - SWIFT_VERSION = 3.0; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 4.0; TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Release; }; - C2B7D90008D4E78D941BC8F9D33BA454 /* Debug */ = { + D23D33E90903D4F23D5950B6FA5B660A /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 93D28BF617451FBF9A50EF928B8C6D75 /* Material.xcconfig */; + baseConfigurationReference = 481F5B635615A26BA7F541FD8C4B3458 /* SnapKit.xcconfig */; buildSettings = { + CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; CURRENT_PROJECT_VERSION = 1; - DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_NO_COMMON_BLOCKS = YES; - GCC_PREFIX_HEADER = "Target Support Files/Material/Material-prefix.pch"; - INFOPLIST_FILE = "Target Support Files/Material/Info.plist"; + GCC_PREFIX_HEADER = "Target Support Files/SnapKit/SnapKit-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/SnapKit/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; - MODULEMAP_FILE = "Target Support Files/Material/Material.modulemap"; - MTL_ENABLE_DEBUG_INFO = YES; - PRODUCT_NAME = Material; + MODULEMAP_FILE = "Target Support Files/SnapKit/SnapKit.modulemap"; + PRODUCT_NAME = SnapKit; SDKROOT = iphoneos; SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 3.0; + SWIFT_VERSION = 4.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; name = Debug; }; - CA2A484D9C55061B22DC2C31394C608A /* Debug */ = { + DBEAE8CCB0BEDE9C9AFF7CE63165381F /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = B3B937BCC6657E47A8E865D991C0864D /* Pods-KeyboardSpy_Example.debug.xcconfig */; + baseConfigurationReference = 05B9FB8DAADA38B14AB68493C55221B9 /* Pods-KeyboardSpy_Example.release.xcconfig */; buildSettings = { + CODE_SIGN_IDENTITY = ""; "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; CURRENT_PROJECT_VERSION = 1; - DEBUG_INFORMATION_FORMAT = dwarf; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_NO_COMMON_BLOCKS = YES; INFOPLIST_FILE = "Target Support Files/Pods-KeyboardSpy_Example/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; MACH_O_TYPE = staticlib; MODULEMAP_FILE = "Target Support Files/Pods-KeyboardSpy_Example/Pods-KeyboardSpy_Example.modulemap"; - MTL_ENABLE_DEBUG_INFO = YES; OTHER_LDFLAGS = ""; OTHER_LIBTOOLFLAGS = ""; PODS_ROOT = "$(SRCROOT)"; @@ -1496,55 +1612,82 @@ PRODUCT_NAME = Pods_KeyboardSpy_Example; SDKROOT = iphoneos; SKIP_INSTALL = YES; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; }; - name = Debug; - }; - D5FCE9A60309198E4DA8C8F51CD6ED09 /* Release */ = { - isa = XCBuildConfiguration; - baseConfigurationReference = 93D28BF617451FBF9A50EF928B8C6D75 /* Material.xcconfig */; - buildSettings = { - CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Material"; - ENABLE_STRICT_OBJC_MSGSEND = YES; - GCC_NO_COMMON_BLOCKS = YES; - INFOPLIST_FILE = "Target Support Files/Material/ResourceBundle-io.cosmicmind.material.fonts-Info.plist"; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; - PRODUCT_NAME = io.cosmicmind.material.fonts; - SDKROOT = iphoneos; - SKIP_INSTALL = YES; - TARGETED_DEVICE_FAMILY = "1,2"; - WRAPPER_EXTENSION = bundle; - }; name = Release; }; - EE82A53CAB7E761FD99CFA3B5A807955 /* Release */ = { + E4B68EE12B21C47CB798D9B1ECA6D7A7 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 93D28BF617451FBF9A50EF928B8C6D75 /* Material.xcconfig */; buildSettings = { - CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/Material"; + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGNING_REQUIRED = NO; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; - INFOPLIST_FILE = "Target Support Files/Material/ResourceBundle-io.cosmicmind.material.icons-Info.plist"; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "POD_CONFIGURATION_DEBUG=1", + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; IPHONEOS_DEPLOYMENT_TARGET = 8.0; - PRODUCT_NAME = io.cosmicmind.material.icons; - SDKROOT = iphoneos; - SKIP_INSTALL = YES; - TARGETED_DEVICE_FAMILY = "1,2"; - WRAPPER_EXTENSION = bundle; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = NO_SIGNING/; + STRIP_INSTALLED_PRODUCT = NO; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SYMROOT = "${SRCROOT}/../build"; }; - name = Release; + name = Debug; }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - 081B26DF50C1EE013AD15C1C4B40F25B /* Build configuration list for PBXNativeTarget "Material-io.cosmicmind.material.fonts" */ = { + 05D1845C66659234F1740725FF639201 /* Build configuration list for PBXNativeTarget "Pods-KeyboardSpy_Example" */ = { isa = XCConfigurationList; buildConfigurations = ( - 653C7D4641DD8E5A4AA1C3775DBBF5AF /* Debug */, - D5FCE9A60309198E4DA8C8F51CD6ED09 /* Release */, + 31F5410416803125010A991989C69DF8 /* Debug */, + DBEAE8CCB0BEDE9C9AFF7CE63165381F /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; @@ -1552,53 +1695,53 @@ 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */ = { isa = XCConfigurationList; buildConfigurations = ( - 015A368F878AC3E2CEAE21DDE8026304 /* Debug */, - 44CDBB6D11DE06DB64D6268622BDC47E /* Release */, + E4B68EE12B21C47CB798D9B1ECA6D7A7 /* Debug */, + B254DAA6CF0CE39F4A3D11B90A7E059A /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 3D7F11829ED5933F16300642C5A2DB13 /* Build configuration list for PBXNativeTarget "SnapKit" */ = { + 5B164B009509A756D78BE1F1E51A9758 /* Build configuration list for PBXNativeTarget "SnapKit" */ = { isa = XCConfigurationList; buildConfigurations = ( - 171EFA09ABFFF7688C68CE89FF09034C /* Debug */, - 349DEA4563438F92BD6EA1B0ABDBE6CE /* Release */, + D23D33E90903D4F23D5950B6FA5B660A /* Debug */, + 4F51CB0611652A7F6AAA0E9CDEC8F69F /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 6914D1DF3634FF531BFE0A02DBCB94D8 /* Build configuration list for PBXNativeTarget "Material-io.cosmicmind.material.icons" */ = { + 5C6E1D771FA6432D71AD35919B82145F /* Build configuration list for PBXNativeTarget "Material" */ = { isa = XCConfigurationList; buildConfigurations = ( - 2944DC914CD83BCF8E0A9782B579811B /* Debug */, - EE82A53CAB7E761FD99CFA3B5A807955 /* Release */, + 4364047A2AACCE76A784DEC3AC4205A2 /* Debug */, + 4504FD64F19E45723C6B0EAEE5B01760 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 6B689F1D2637204C5FC3120CB308971B /* Build configuration list for PBXNativeTarget "KeyboardSpy" */ = { + 66CCA8D119CF3BBA6337F797504BA1C2 /* Build configuration list for PBXNativeTarget "Material-com.cosmicmind.material.icons" */ = { isa = XCConfigurationList; buildConfigurations = ( - 24F77A7B9ED504305AF684746EF7682E /* Debug */, - 74AB2315FD8A8D88E8BA5C94CC03ACC5 /* Release */, + B0431A31FF973448A952FA06F2B8F4AE /* Debug */, + 10D9F733A96625C0A8711685F3CB62D1 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 7572C734E6D15D83A761186A58F31EC1 /* Build configuration list for PBXNativeTarget "Material" */ = { + DBEC2A429EC4BD015E9DA3E5475949FA /* Build configuration list for PBXNativeTarget "Material-com.cosmicmind.material.fonts" */ = { isa = XCConfigurationList; buildConfigurations = ( - C2B7D90008D4E78D941BC8F9D33BA454 /* Debug */, - 3685740571C1E35339DFB2B3B602ABF9 /* Release */, + A8F02BB0755E6AC927CCA374978E7D00 /* Debug */, + 741C0CD69706CE66E451F2BFB4798265 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - EC857555EFFF091E2E28D65D1B3046EF /* Build configuration list for PBXNativeTarget "Pods-KeyboardSpy_Example" */ = { + F6233B77EAE4FF06285D36C1A9B98162 /* Build configuration list for PBXNativeTarget "KeyboardSpy" */ = { isa = XCConfigurationList; buildConfigurations = ( - CA2A484D9C55061B22DC2C31394C608A /* Debug */, - 2CE5FF8B951893563CB1EAE81AB383AD /* Release */, + 151B439DDB7BCFCED56112004F112A82 /* Debug */, + B3D5BC3778688A70E16D845CE924B1B1 /* Release */, ); defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; diff --git a/Example/Pods/Pods.xcodeproj/xcuserdata/Dalton.xcuserdatad/xcschemes/KeyboardSpy.xcscheme b/Example/Pods/Pods.xcodeproj/xcuserdata/Dalton.xcuserdatad/xcschemes/KeyboardSpy.xcscheme index c62e7ed..317b5a3 100644 --- a/Example/Pods/Pods.xcodeproj/xcuserdata/Dalton.xcuserdatad/xcschemes/KeyboardSpy.xcscheme +++ b/Example/Pods/Pods.xcodeproj/xcuserdata/Dalton.xcuserdatad/xcschemes/KeyboardSpy.xcscheme @@ -1,54 +1,67 @@ + buildForArchiving = "YES" + buildForAnalyzing = "YES"> + BuildableIdentifier = "primary" + BlueprintIdentifier = "8303ECB6B90CFF1D24DA6ADA7CAFD334" + BuildableName = "KeyboardSpy.framework" + BlueprintName = "KeyboardSpy" + ReferencedContainer = "container:Pods.xcodeproj"> + language = "" + shouldUseLaunchSchemeArgsEnv = "YES"> + + + + + + + debugDocumentVersioning = "YES"> diff --git a/Example/Pods/Pods.xcodeproj/xcuserdata/Dalton.xcuserdatad/xcschemes/Material-io.cosmicmind.material.icons.xcscheme b/Example/Pods/Pods.xcodeproj/xcuserdata/Dalton.xcuserdatad/xcschemes/Material-com.cosmicmind.material.fonts.xcscheme similarity index 61% rename from Example/Pods/Pods.xcodeproj/xcuserdata/Dalton.xcuserdatad/xcschemes/Material-io.cosmicmind.material.icons.xcscheme rename to Example/Pods/Pods.xcodeproj/xcuserdata/Dalton.xcuserdatad/xcschemes/Material-com.cosmicmind.material.fonts.xcscheme index 5d9afe2..23c7d7a 100644 --- a/Example/Pods/Pods.xcodeproj/xcuserdata/Dalton.xcuserdatad/xcschemes/Material-io.cosmicmind.material.icons.xcscheme +++ b/Example/Pods/Pods.xcodeproj/xcuserdata/Dalton.xcuserdatad/xcschemes/Material-com.cosmicmind.material.fonts.xcscheme @@ -1,54 +1,67 @@ + buildForArchiving = "YES" + buildForAnalyzing = "YES"> + BuildableIdentifier = "primary" + BlueprintIdentifier = "2D6B45908ECC3888F51EC4CF7298F759" + BuildableName = "com.cosmicmind.material.fonts.bundle" + BlueprintName = "Material-com.cosmicmind.material.fonts" + ReferencedContainer = "container:Pods.xcodeproj"> + language = "" + shouldUseLaunchSchemeArgsEnv = "YES"> + + + + + + + debugDocumentVersioning = "YES"> diff --git a/Example/Pods/Pods.xcodeproj/xcuserdata/Dalton.xcuserdatad/xcschemes/Material-io.cosmicmind.material.fonts.xcscheme b/Example/Pods/Pods.xcodeproj/xcuserdata/Dalton.xcuserdatad/xcschemes/Material-com.cosmicmind.material.icons.xcscheme similarity index 61% rename from Example/Pods/Pods.xcodeproj/xcuserdata/Dalton.xcuserdatad/xcschemes/Material-io.cosmicmind.material.fonts.xcscheme rename to Example/Pods/Pods.xcodeproj/xcuserdata/Dalton.xcuserdatad/xcschemes/Material-com.cosmicmind.material.icons.xcscheme index 0c51a16..8ec2933 100644 --- a/Example/Pods/Pods.xcodeproj/xcuserdata/Dalton.xcuserdatad/xcschemes/Material-io.cosmicmind.material.fonts.xcscheme +++ b/Example/Pods/Pods.xcodeproj/xcuserdata/Dalton.xcuserdatad/xcschemes/Material-com.cosmicmind.material.icons.xcscheme @@ -1,54 +1,67 @@ + buildForArchiving = "YES" + buildForAnalyzing = "YES"> + BuildableIdentifier = "primary" + BlueprintIdentifier = "4CBC8DD3CD3F13C4EF87425DF5B8AC9A" + BuildableName = "com.cosmicmind.material.icons.bundle" + BlueprintName = "Material-com.cosmicmind.material.icons" + ReferencedContainer = "container:Pods.xcodeproj"> + language = "" + shouldUseLaunchSchemeArgsEnv = "YES"> + + + + + + + debugDocumentVersioning = "YES"> diff --git a/Example/Pods/Pods.xcodeproj/xcuserdata/Dalton.xcuserdatad/xcschemes/Material.xcscheme b/Example/Pods/Pods.xcodeproj/xcuserdata/Dalton.xcuserdatad/xcschemes/Material.xcscheme index a0bfd20..813e083 100644 --- a/Example/Pods/Pods.xcodeproj/xcuserdata/Dalton.xcuserdatad/xcschemes/Material.xcscheme +++ b/Example/Pods/Pods.xcodeproj/xcuserdata/Dalton.xcuserdatad/xcschemes/Material.xcscheme @@ -1,54 +1,67 @@ + buildForArchiving = "YES" + buildForAnalyzing = "YES"> + BuildableIdentifier = "primary" + BlueprintIdentifier = "415640AE1BAB89361F9D757D666EB139" + BuildableName = "Material.framework" + BlueprintName = "Material" + ReferencedContainer = "container:Pods.xcodeproj"> + language = "" + shouldUseLaunchSchemeArgsEnv = "YES"> + + + + + + + debugDocumentVersioning = "YES"> diff --git a/Example/Pods/Pods.xcodeproj/xcuserdata/Dalton.xcuserdatad/xcschemes/Pods-KeyboardSpy_Example.xcscheme b/Example/Pods/Pods.xcodeproj/xcuserdata/Dalton.xcuserdatad/xcschemes/Pods-KeyboardSpy_Example.xcscheme index cc62aae..455b290 100644 --- a/Example/Pods/Pods.xcodeproj/xcuserdata/Dalton.xcuserdatad/xcschemes/Pods-KeyboardSpy_Example.xcscheme +++ b/Example/Pods/Pods.xcodeproj/xcuserdata/Dalton.xcuserdatad/xcschemes/Pods-KeyboardSpy_Example.xcscheme @@ -1,6 +1,6 @@ @@ -26,6 +26,7 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + language = "" shouldUseLaunchSchemeArgsEnv = "YES"> @@ -36,6 +37,7 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + language = "" launchStyle = "0" useCustomWorkingDirectory = "NO" ignoresPersistentStateOnLaunch = "NO" @@ -45,7 +47,7 @@ diff --git a/Example/Pods/Pods.xcodeproj/xcuserdata/Dalton.xcuserdatad/xcschemes/SnapKit.xcscheme b/Example/Pods/Pods.xcodeproj/xcuserdata/Dalton.xcuserdatad/xcschemes/SnapKit.xcscheme index 27eb05e..7f231b3 100644 --- a/Example/Pods/Pods.xcodeproj/xcuserdata/Dalton.xcuserdatad/xcschemes/SnapKit.xcscheme +++ b/Example/Pods/Pods.xcodeproj/xcuserdata/Dalton.xcuserdatad/xcschemes/SnapKit.xcscheme @@ -1,54 +1,67 @@ + buildForArchiving = "YES" + buildForAnalyzing = "YES"> + BuildableIdentifier = "primary" + BlueprintIdentifier = "9A7B3FB64E7B250083D638DAA82A1180" + BuildableName = "SnapKit.framework" + BlueprintName = "SnapKit" + ReferencedContainer = "container:Pods.xcodeproj"> + language = "" + shouldUseLaunchSchemeArgsEnv = "YES"> + + + + + + + debugDocumentVersioning = "YES"> diff --git a/Example/Pods/Pods.xcodeproj/xcuserdata/Dalton.xcuserdatad/xcschemes/xcschememanagement.plist b/Example/Pods/Pods.xcodeproj/xcuserdata/Dalton.xcuserdatad/xcschemes/xcschememanagement.plist index 71f41ce..db6a901 100644 --- a/Example/Pods/Pods.xcodeproj/xcuserdata/Dalton.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/Example/Pods/Pods.xcodeproj/xcuserdata/Dalton.xcuserdatad/xcschemes/xcschememanagement.plist @@ -9,12 +9,12 @@ isShown - Material-io.cosmicmind.material.fonts.xcscheme + Material-com.cosmicmind.material.fonts.xcscheme isShown - Material-io.cosmicmind.material.icons.xcscheme + Material-com.cosmicmind.material.icons.xcscheme isShown @@ -36,37 +36,6 @@ SuppressBuildableAutocreation - - 0FB771E0DE35ABAFDF00C9CA54493BDD - - primary - - - 36D7B55B95E6A1236AEF513E8FD9238E - - primary - - - 4A3AED5BAF9E9AF799FE28CFB72FE3F7 - - primary - - - 63F8092C414A0508CAF3FCF21C6409EA - - primary - - - E6EDA33F2979D1FBE905B02DD311590D - - primary - - - EE23AC8CFA049B54594921CED4E38996 - - primary - - - + diff --git a/Example/Pods/SnapKit/README.md b/Example/Pods/SnapKit/README.md index a6da596..fed2133 100644 --- a/Example/Pods/SnapKit/README.md +++ b/Example/Pods/SnapKit/README.md @@ -7,8 +7,8 @@ SnapKit is a DSL to make Auto Layout easy on both iOS and OS X. [![Cocoapods Compatible](https://img.shields.io/cocoapods/v/SnapKit.svg)](https://cocoapods.org/pods/SnapKit) [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) -#### ⚠️ **To use with Swift 2.x please ensure you are using == 0.22.0** ⚠️ #### ⚠️ **To use with Swift 3.x please ensure you are using >= 3.0.0** ⚠️ +#### ⚠️ **To use with Swift 4.x please ensure you are using >= 4.0.0** ⚠️ ## Contents @@ -23,13 +23,9 @@ SnapKit is a DSL to make Auto Layout easy on both iOS and OS X. ## Requirements - iOS 8.0+ / Mac OS X 10.11+ / tvOS 9.0+ -- Xcode 8.0+ +- Xcode 9.0+ - Swift 3.0+ -## Migration Guides - -- [SnapKit 3.0 Migration Guide](https://github.com/SnapKit/SnapKit/blob/master/Documentation/SnapKit%203.0%20Migration%20Guide.md) - ## Communication - If you **need help**, use [Stack Overflow](http://stackoverflow.com/questions/tagged/snapkit). (Tag 'snapkit') @@ -49,7 +45,7 @@ SnapKit is a DSL to make Auto Layout easy on both iOS and OS X. $ gem install cocoapods ``` -> CocoaPods 1.1.0+ is required to build SnapKit 3.0.0+. +> CocoaPods 1.1.0+ is required to build SnapKit 4.0.0+. To integrate SnapKit into your Xcode project using CocoaPods, specify it in your `Podfile`: @@ -59,7 +55,7 @@ platform :ios, '10.0' use_frameworks! target '' do - pod 'SnapKit', '~> 3.1.2' + pod 'SnapKit', '~> 4.0.0' end ``` @@ -83,7 +79,7 @@ $ brew install carthage To integrate SnapKit into your Xcode project using Carthage, specify it in your `Cartfile`: ```ogdl -github "SnapKit/SnapKit" ~> 3.0.2 +github "SnapKit/SnapKit" ~> 4.0.0 ``` Run `carthage update` to build the framework and drag the built `SnapKit.framework` into your Xcode project. diff --git a/Example/Pods/SnapKit/Source/Constraint.swift b/Example/Pods/SnapKit/Source/Constraint.swift index 5c8c483..2720745 100644 --- a/Example/Pods/SnapKit/Source/Constraint.swift +++ b/Example/Pods/SnapKit/Source/Constraint.swift @@ -28,10 +28,10 @@ #endif public final class Constraint { - + internal let sourceLocation: (String, UInt) internal let label: String? - + private let from: ConstraintItem private let to: ConstraintItem private let relation: ConstraintRelation @@ -46,10 +46,19 @@ public final class Constraint { self.updateConstantAndPriorityIfNeeded() } } - private var layoutConstraints: [LayoutConstraint] + public var layoutConstraints: [LayoutConstraint] - // MARK: Initialization + public var isActive: Bool { + for layoutConstraint in self.layoutConstraints { + if layoutConstraint.isActive { + return true + } + } + return false + } + // MARK: Initialization + internal init(from: ConstraintItem, to: ConstraintItem, relation: ConstraintRelation, @@ -67,20 +76,20 @@ public final class Constraint { self.constant = constant self.priority = priority self.layoutConstraints = [] - + // get attributes let layoutFromAttributes = self.from.attributes.layoutAttributes let layoutToAttributes = self.to.attributes.layoutAttributes - + // get layout from let layoutFrom = self.from.layoutConstraintItem! - + // get relation let layoutRelation = self.relation.layoutRelation - + for layoutFromAttribute in layoutFromAttributes { // get layout to attribute - let layoutToAttribute: NSLayoutAttribute + let layoutToAttribute: LayoutAttribute #if os(iOS) || os(tvOS) if layoutToAttributes.count > 0 { if self.from.attributes == .edges && self.to.attributes == .margins { @@ -130,18 +139,18 @@ public final class Constraint { layoutToAttribute = layoutFromAttribute } #endif - + // get layout constant let layoutConstant: CGFloat = self.constant.constraintConstantTargetValueFor(layoutAttribute: layoutToAttribute) - + // get layout to var layoutTo: AnyObject? = self.to.target - + // use superview if possible if layoutTo == nil && layoutToAttribute != .width && layoutToAttribute != .height { layoutTo = layoutFrom.superview } - + // create layout constraint let layoutConstraint = LayoutConstraint( item: layoutFrom, @@ -152,119 +161,113 @@ public final class Constraint { multiplier: self.multiplier.constraintMultiplierTargetValue, constant: layoutConstant ) - + // set label layoutConstraint.label = self.label - + // set priority - layoutConstraint.priority = self.priority.constraintPriorityTargetValue - + layoutConstraint.priority = LayoutPriority(rawValue: self.priority.constraintPriorityTargetValue) + // set constraint layoutConstraint.constraint = self - + // append self.layoutConstraints.append(layoutConstraint) } } - + // MARK: Public - + @available(*, deprecated:3.0, message:"Use activate().") public func install() { self.activate() } - + @available(*, deprecated:3.0, message:"Use deactivate().") public func uninstall() { self.deactivate() } - + public func activate() { self.activateIfNeeded() } - + public func deactivate() { self.deactivateIfNeeded() } - + @discardableResult public func update(offset: ConstraintOffsetTarget) -> Constraint { self.constant = offset.constraintOffsetTargetValue return self } - + @discardableResult public func update(inset: ConstraintInsetTarget) -> Constraint { self.constant = inset.constraintInsetTargetValue return self } - + @discardableResult public func update(priority: ConstraintPriorityTarget) -> Constraint { self.priority = priority.constraintPriorityTargetValue return self } - + @available(*, deprecated:3.0, message:"Use update(offset: ConstraintOffsetTarget) instead.") public func updateOffset(amount: ConstraintOffsetTarget) -> Void { self.update(offset: amount) } - + @available(*, deprecated:3.0, message:"Use update(inset: ConstraintInsetTarget) instead.") public func updateInsets(amount: ConstraintInsetTarget) -> Void { self.update(inset: amount) } - + @available(*, deprecated:3.0, message:"Use update(priority: ConstraintPriorityTarget) instead.") public func updatePriority(amount: ConstraintPriorityTarget) -> Void { self.update(priority: amount) } - + @available(*, obsoleted:3.0, message:"Use update(priority: ConstraintPriorityTarget) instead.") public func updatePriorityRequired() -> Void {} - + @available(*, obsoleted:3.0, message:"Use update(priority: ConstraintPriorityTarget) instead.") public func updatePriorityHigh() -> Void { fatalError("Must be implemented by Concrete subclass.") } - + @available(*, obsoleted:3.0, message:"Use update(priority: ConstraintPriorityTarget) instead.") public func updatePriorityMedium() -> Void { fatalError("Must be implemented by Concrete subclass.") } - + @available(*, obsoleted:3.0, message:"Use update(priority: ConstraintPriorityTarget) instead.") public func updatePriorityLow() -> Void { fatalError("Must be implemented by Concrete subclass.") } - + // MARK: Internal - + internal func updateConstantAndPriorityIfNeeded() { for layoutConstraint in self.layoutConstraints { let attribute = (layoutConstraint.secondAttribute == .notAnAttribute) ? layoutConstraint.firstAttribute : layoutConstraint.secondAttribute layoutConstraint.constant = self.constant.constraintConstantTargetValueFor(layoutAttribute: attribute) - - #if os(iOS) || os(tvOS) - let requiredPriority: UILayoutPriority = UILayoutPriorityRequired - #else - let requiredPriority: Float = 1000.0 - #endif - - - if (layoutConstraint.priority < requiredPriority), (self.priority.constraintPriorityTargetValue != requiredPriority) { - layoutConstraint.priority = self.priority.constraintPriorityTargetValue + + let requiredPriority = ConstraintPriority.required.value + if (layoutConstraint.priority.rawValue < requiredPriority), (self.priority.constraintPriorityTargetValue != requiredPriority) { + layoutConstraint.priority = LayoutPriority(rawValue: self.priority.constraintPriorityTargetValue) } } } - + internal func activateIfNeeded(updatingExisting: Bool = false) { guard let item = self.from.layoutConstraintItem else { print("WARNING: SnapKit failed to get from item from constraint. Activate will be a no-op.") return } let layoutConstraints = self.layoutConstraints - + if updatingExisting { var existingLayoutConstraints: [LayoutConstraint] = [] for constraint in item.constraints { existingLayoutConstraints += constraint.layoutConstraints } - + for layoutConstraint in layoutConstraints { let existingLayoutConstraint = existingLayoutConstraints.first { $0 == layoutConstraint } guard let updateLayoutConstraint = existingLayoutConstraint else { fatalError("Updated constraint could not find existing matching constraint to update: \(layoutConstraint)") } - + let updateLayoutAttribute = (updateLayoutConstraint.secondAttribute == .notAnAttribute) ? updateLayoutConstraint.firstAttribute : updateLayoutConstraint.secondAttribute updateLayoutConstraint.constant = self.constant.constraintConstantTargetValueFor(layoutAttribute: updateLayoutAttribute) } @@ -273,7 +276,7 @@ public final class Constraint { item.add(constraints: [self]) } } - + internal func deactivateIfNeeded() { guard let item = self.from.layoutConstraintItem else { print("WARNING: SnapKit failed to get from item from constraint. Deactivate will be a no-op.") diff --git a/Example/Pods/SnapKit/Source/ConstraintAttributes.swift b/Example/Pods/SnapKit/Source/ConstraintAttributes.swift index 4083235..10bddb1 100644 --- a/Example/Pods/SnapKit/Source/ConstraintAttributes.swift +++ b/Example/Pods/SnapKit/Source/ConstraintAttributes.swift @@ -103,8 +103,8 @@ internal struct ConstraintAttributes : OptionSet { @available(iOS 8.0, *) internal static var centerWithinMargins: ConstraintAttributes { return self.init(786432) } - internal var layoutAttributes:[NSLayoutAttribute] { - var attrs = [NSLayoutAttribute]() + internal var layoutAttributes:[LayoutAttribute] { + var attrs = [LayoutAttribute]() if (self.contains(ConstraintAttributes.left)) { attrs.append(.left) } diff --git a/Example/Pods/SnapKit/Source/ConstraintConstantTarget.swift b/Example/Pods/SnapKit/Source/ConstraintConstantTarget.swift index 801bb79..bc6d596 100644 --- a/Example/Pods/SnapKit/Source/ConstraintConstantTarget.swift +++ b/Example/Pods/SnapKit/Source/ConstraintConstantTarget.swift @@ -42,7 +42,7 @@ extension ConstraintInsets: ConstraintConstantTarget { extension ConstraintConstantTarget { - internal func constraintConstantTargetValueFor(layoutAttribute: NSLayoutAttribute) -> CGFloat { + internal func constraintConstantTargetValueFor(layoutAttribute: LayoutAttribute) -> CGFloat { if let value = self as? CGFloat { return value } diff --git a/Example/Pods/SnapKit/Source/ConstraintDSL.swift b/Example/Pods/SnapKit/Source/ConstraintDSL.swift index ed7b7e5..a7e1798 100644 --- a/Example/Pods/SnapKit/Source/ConstraintDSL.swift +++ b/Example/Pods/SnapKit/Source/ConstraintDSL.swift @@ -39,10 +39,10 @@ public protocol ConstraintDSL { extension ConstraintDSL { public func setLabel(_ value: String?) { - objc_setAssociatedObject(self.target, &labelKey, value, .OBJC_ASSOCIATION_COPY_NONATOMIC) + objc_setAssociatedObject(self.target as Any, &labelKey, value, .OBJC_ASSOCIATION_COPY_NONATOMIC) } public func label() -> String? { - return objc_getAssociatedObject(self.target, &labelKey) as? String + return objc_getAssociatedObject(self.target as Any, &labelKey) as? String } } diff --git a/Example/Pods/SnapKit/Source/ConstraintInsets.swift b/Example/Pods/SnapKit/Source/ConstraintInsets.swift index 6ecac6b..738ca05 100644 --- a/Example/Pods/SnapKit/Source/ConstraintInsets.swift +++ b/Example/Pods/SnapKit/Source/ConstraintInsets.swift @@ -31,5 +31,5 @@ #if os(iOS) || os(tvOS) public typealias ConstraintInsets = UIEdgeInsets #else - public typealias ConstraintInsets = EdgeInsets + public typealias ConstraintInsets = NSEdgeInsets #endif diff --git a/Example/Pods/SnapKit/Source/ConstraintMakerExtendable.swift b/Example/Pods/SnapKit/Source/ConstraintMakerExtendable.swift index 658c833..6a755b5 100644 --- a/Example/Pods/SnapKit/Source/ConstraintMakerExtendable.swift +++ b/Example/Pods/SnapKit/Source/ConstraintMakerExtendable.swift @@ -109,6 +109,12 @@ public class ConstraintMakerExtendable: ConstraintMakerRelatable { return self } + @available(iOS 8.0, *) + public var topMargin: ConstraintMakerExtendable { + self.description.attributes += .topMargin + return self + } + @available(iOS 8.0, *) public var bottomMargin: ConstraintMakerExtendable { self.description.attributes += .bottomMargin diff --git a/Example/Pods/SnapKit/Source/ConstraintMakerPriortizable.swift b/Example/Pods/SnapKit/Source/ConstraintMakerPriortizable.swift index 82a6de6..ef79448 100644 --- a/Example/Pods/SnapKit/Source/ConstraintMakerPriortizable.swift +++ b/Example/Pods/SnapKit/Source/ConstraintMakerPriortizable.swift @@ -30,38 +30,39 @@ public class ConstraintMakerPriortizable: ConstraintMakerFinalizable { + @discardableResult + public func priority(_ amount: ConstraintPriority) -> ConstraintMakerFinalizable { + self.description.priority = amount.value + return self + } + @discardableResult public func priority(_ amount: ConstraintPriorityTarget) -> ConstraintMakerFinalizable { self.description.priority = amount return self } - @available(*, deprecated:3.0, message:"Use priority(_ amount: ConstraintPriorityTarget) instead.") + @available(*, deprecated:3.0, message:"Use priority(.required) instead.") @discardableResult public func priorityRequired() -> ConstraintMakerFinalizable { - return self.priority(1000) + return self.priority(.required) } - @available(*, deprecated:3.0, message:"Use priority(_ amount: ConstraintPriorityTarget) instead.") + @available(*, deprecated:3.0, message:"Use priority(.high) instead.") @discardableResult public func priorityHigh() -> ConstraintMakerFinalizable { - return self.priority(750) + return self.priority(.high) } - @available(*, deprecated:3.0, message:"Use priority(_ amount: ConstraintPriorityTarget) instead.") + @available(*, deprecated:3.0, message:"Use priority(.medium) instead.") @discardableResult public func priorityMedium() -> ConstraintMakerFinalizable { - #if os(iOS) || os(tvOS) - return self.priority(500) - #else - return self.priority(501) - #endif + return self.priority(.medium) } - @available(*, deprecated:3.0, message:"Use priority(_ amount: ConstraintPriorityTarget) instead.") + @available(*, deprecated:3.0, message:"Use priority(.low) instead.") @discardableResult public func priorityLow() -> ConstraintMakerFinalizable { - return self.priority(250) + return self.priority(.low) } - } diff --git a/Example/Pods/SnapKit/Source/ConstraintPriority.swift b/Example/Pods/SnapKit/Source/ConstraintPriority.swift new file mode 100644 index 0000000..f9dab16 --- /dev/null +++ b/Example/Pods/SnapKit/Source/ConstraintPriority.swift @@ -0,0 +1,77 @@ +// +// SnapKit +// +// Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit +// +// 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. + +#if os(iOS) || os(tvOS) + import UIKit +#else + import AppKit +#endif + +public struct ConstraintPriority : ExpressibleByFloatLiteral, Equatable, Strideable { + public typealias FloatLiteralType = Float + + public let value: Float + + public init(floatLiteral value: Float) { + self.value = value + } + + public init(_ value: Float) { + self.value = value + } + + public static var required: ConstraintPriority { + return 1000.0 + } + + public static var high: ConstraintPriority { + return 750.0 + } + + public static var medium: ConstraintPriority { + #if os(OSX) + return 501.0 + #else + return 500.0 + #endif + + } + + public static var low: ConstraintPriority { + return 250.0 + } + + public static func ==(lhs: ConstraintPriority, rhs: ConstraintPriority) -> Bool { + return lhs.value == rhs.value + } + + // MARK: Strideable + + public func advanced(by n: FloatLiteralType) -> ConstraintPriority { + return ConstraintPriority(floatLiteral: value + n) + } + + public func distance(to other: ConstraintPriority) -> FloatLiteralType { + return other.value - value + } +} diff --git a/Example/Pods/SnapKit/Source/ConstraintRelation.swift b/Example/Pods/SnapKit/Source/ConstraintRelation.swift index d53bb3b..446aaf7 100644 --- a/Example/Pods/SnapKit/Source/ConstraintRelation.swift +++ b/Example/Pods/SnapKit/Source/ConstraintRelation.swift @@ -33,7 +33,7 @@ internal enum ConstraintRelation : Int { case lessThanOrEqual case greaterThanOrEqual - internal var layoutRelation: NSLayoutRelation { + internal var layoutRelation: LayoutRelation { get { switch(self) { case .equal: diff --git a/Example/Pods/SnapKit/Source/ConstraintViewDSL.swift b/Example/Pods/SnapKit/Source/ConstraintViewDSL.swift index 0242c4a..298bdb1 100644 --- a/Example/Pods/SnapKit/Source/ConstraintViewDSL.swift +++ b/Example/Pods/SnapKit/Source/ConstraintViewDSL.swift @@ -53,37 +53,37 @@ public struct ConstraintViewDSL: ConstraintAttributesDSL { public var contentHuggingHorizontalPriority: Float { get { - return self.view.contentHuggingPriority(for: .horizontal) + return self.view.contentHuggingPriority(for: .horizontal).rawValue } set { - self.view.setContentHuggingPriority(newValue, for: .horizontal) + self.view.setContentHuggingPriority(LayoutPriority(rawValue: newValue), for: .horizontal) } } public var contentHuggingVerticalPriority: Float { get { - return self.view.contentHuggingPriority(for: .vertical) + return self.view.contentHuggingPriority(for: .vertical).rawValue } set { - self.view.setContentHuggingPriority(newValue, for: .vertical) + self.view.setContentHuggingPriority(LayoutPriority(rawValue: newValue), for: .vertical) } } public var contentCompressionResistanceHorizontalPriority: Float { get { - return self.view.contentCompressionResistancePriority(for: .horizontal) + return self.view.contentCompressionResistancePriority(for: .horizontal).rawValue } set { - self.view.setContentHuggingPriority(newValue, for: .horizontal) + self.view.setContentCompressionResistancePriority(LayoutPriority(rawValue: newValue), for: .horizontal) } } public var contentCompressionResistanceVerticalPriority: Float { get { - return self.view.contentCompressionResistancePriority(for: .vertical) + return self.view.contentCompressionResistancePriority(for: .vertical).rawValue } set { - self.view.setContentCompressionResistancePriority(newValue, for: .vertical) + self.view.setContentCompressionResistancePriority(LayoutPriority(rawValue: newValue), for: .vertical) } } diff --git a/Example/Pods/SnapKit/Source/Debugging.swift b/Example/Pods/SnapKit/Source/Debugging.swift index fdc505d..55f5b87 100644 --- a/Example/Pods/SnapKit/Source/Debugging.swift +++ b/Example/Pods/SnapKit/Source/Debugging.swift @@ -66,7 +66,7 @@ public extension LayoutConstraint { } } - if self.priority != 1000.0 { + if self.priority.rawValue != 1000.0 { description += " ^\(self.priority)" } @@ -77,7 +77,7 @@ public extension LayoutConstraint { } -private func descriptionForRelation(_ relation: NSLayoutRelation) -> String { +private func descriptionForRelation(_ relation: LayoutRelation) -> String { switch relation { case .equal: return "==" case .greaterThanOrEqual: return ">=" @@ -85,7 +85,7 @@ private func descriptionForRelation(_ relation: NSLayoutRelation) -> String { } } -private func descriptionForAttribute(_ attribute: NSLayoutAttribute) -> String { +private func descriptionForAttribute(_ attribute: LayoutAttribute) -> String { #if os(iOS) || os(tvOS) switch attribute { case .notAnAttribute: return "notAnAttribute" diff --git a/Example/Pods/SnapKit/Source/Typealiases.swift b/Example/Pods/SnapKit/Source/Typealiases.swift new file mode 100644 index 0000000..8a44151 --- /dev/null +++ b/Example/Pods/SnapKit/Source/Typealiases.swift @@ -0,0 +1,37 @@ +// +// SnapKit +// +// Copyright (c) 2011-Present SnapKit Team - https://github.com/SnapKit +// +// 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 Foundation + +#if os(iOS) || os(tvOS) + import UIKit + typealias LayoutRelation = NSLayoutRelation + typealias LayoutAttribute = NSLayoutAttribute + typealias LayoutPriority = UILayoutPriority +#else + import AppKit + typealias LayoutRelation = NSLayoutConstraint.Relation + typealias LayoutAttribute = NSLayoutConstraint.Attribute + typealias LayoutPriority = NSLayoutConstraint.Priority +#endif + diff --git a/Example/Pods/Target Support Files/KeyboardSpy/Info.plist b/Example/Pods/Target Support Files/KeyboardSpy/Info.plist index 161a9d3..2243fe6 100644 --- a/Example/Pods/Target Support Files/KeyboardSpy/Info.plist +++ b/Example/Pods/Target Support Files/KeyboardSpy/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 0.1.0 + 1.0.0 CFBundleSignature ???? CFBundleVersion diff --git a/Example/Pods/Target Support Files/KeyboardSpy/KeyboardSpy-prefix.pch b/Example/Pods/Target Support Files/KeyboardSpy/KeyboardSpy-prefix.pch index aa992a4..beb2a24 100644 --- a/Example/Pods/Target Support Files/KeyboardSpy/KeyboardSpy-prefix.pch +++ b/Example/Pods/Target Support Files/KeyboardSpy/KeyboardSpy-prefix.pch @@ -1,4 +1,12 @@ #ifdef __OBJC__ #import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif #endif diff --git a/Example/Pods/Target Support Files/KeyboardSpy/KeyboardSpy-umbrella.h b/Example/Pods/Target Support Files/KeyboardSpy/KeyboardSpy-umbrella.h index 3dc3cdb..d78887a 100644 --- a/Example/Pods/Target Support Files/KeyboardSpy/KeyboardSpy-umbrella.h +++ b/Example/Pods/Target Support Files/KeyboardSpy/KeyboardSpy-umbrella.h @@ -1,5 +1,13 @@ #ifdef __OBJC__ #import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif #endif diff --git a/Example/Pods/Target Support Files/KeyboardSpy/KeyboardSpy.xcconfig b/Example/Pods/Target Support Files/KeyboardSpy/KeyboardSpy.xcconfig index 399fbab..d72f850 100644 --- a/Example/Pods/Target Support Files/KeyboardSpy/KeyboardSpy.xcconfig +++ b/Example/Pods/Target Support Files/KeyboardSpy/KeyboardSpy.xcconfig @@ -5,5 +5,6 @@ OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" PODS_BUILD_DIR = $BUILD_DIR PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/../.. PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} SKIP_INSTALL = YES diff --git a/Example/Pods/Target Support Files/Material/Info.plist b/Example/Pods/Target Support Files/Material/Info.plist index fb0e972..01a3b01 100644 --- a/Example/Pods/Target Support Files/Material/Info.plist +++ b/Example/Pods/Target Support Files/Material/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.4.11 + 2.10.2 CFBundleSignature ???? CFBundleVersion diff --git a/Example/Pods/Target Support Files/Material/Material-prefix.pch b/Example/Pods/Target Support Files/Material/Material-prefix.pch index aa992a4..beb2a24 100644 --- a/Example/Pods/Target Support Files/Material/Material-prefix.pch +++ b/Example/Pods/Target Support Files/Material/Material-prefix.pch @@ -1,4 +1,12 @@ #ifdef __OBJC__ #import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif #endif diff --git a/Example/Pods/Target Support Files/Material/Material-umbrella.h b/Example/Pods/Target Support Files/Material/Material-umbrella.h index 6d657ce..4a69d42 100644 --- a/Example/Pods/Target Support Files/Material/Material-umbrella.h +++ b/Example/Pods/Target Support Files/Material/Material-umbrella.h @@ -1,5 +1,13 @@ #ifdef __OBJC__ #import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif #endif diff --git a/Example/Pods/Target Support Files/Material/Material.xcconfig b/Example/Pods/Target Support Files/Material/Material.xcconfig index 7f783c3..b6e87b9 100644 --- a/Example/Pods/Target Support Files/Material/Material.xcconfig +++ b/Example/Pods/Target Support Files/Material/Material.xcconfig @@ -5,5 +5,6 @@ OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" PODS_BUILD_DIR = $BUILD_DIR PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/Material PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} SKIP_INSTALL = YES diff --git a/Example/Pods/Target Support Files/Material/ResourceBundle-com.cosmicmind.material.fonts-Info.plist b/Example/Pods/Target Support Files/Material/ResourceBundle-com.cosmicmind.material.fonts-Info.plist new file mode 100644 index 0000000..0f5d68b --- /dev/null +++ b/Example/Pods/Target Support Files/Material/ResourceBundle-com.cosmicmind.material.fonts-Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + BNDL + CFBundleShortVersionString + 2.10.2 + CFBundleSignature + ???? + CFBundleVersion + 1 + NSPrincipalClass + + + diff --git a/Example/Pods/Target Support Files/Material/ResourceBundle-com.cosmicmind.material.icons-Info.plist b/Example/Pods/Target Support Files/Material/ResourceBundle-com.cosmicmind.material.icons-Info.plist new file mode 100644 index 0000000..0f5d68b --- /dev/null +++ b/Example/Pods/Target Support Files/Material/ResourceBundle-com.cosmicmind.material.icons-Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + BNDL + CFBundleShortVersionString + 2.10.2 + CFBundleSignature + ???? + CFBundleVersion + 1 + NSPrincipalClass + + + diff --git a/Example/Pods/Target Support Files/Pods-KeyboardSpy_Example/Pods-KeyboardSpy_Example-acknowledgements.markdown b/Example/Pods/Target Support Files/Pods-KeyboardSpy_Example/Pods-KeyboardSpy_Example-acknowledgements.markdown index 93b2a37..a6de9c6 100644 --- a/Example/Pods/Target Support Files/Pods-KeyboardSpy_Example/Pods-KeyboardSpy_Example-acknowledgements.markdown +++ b/Example/Pods/Target Support Files/Pods-KeyboardSpy_Example/Pods-KeyboardSpy_Example-acknowledgements.markdown @@ -26,7 +26,7 @@ THE SOFTWARE. ## Material -Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. . All rights reserved. +Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, 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: diff --git a/Example/Pods/Target Support Files/Pods-KeyboardSpy_Example/Pods-KeyboardSpy_Example-acknowledgements.plist b/Example/Pods/Target Support Files/Pods-KeyboardSpy_Example/Pods-KeyboardSpy_Example-acknowledgements.plist index 165c216..d86d4f8 100644 --- a/Example/Pods/Target Support Files/Pods-KeyboardSpy_Example/Pods-KeyboardSpy_Example-acknowledgements.plist +++ b/Example/Pods/Target Support Files/Pods-KeyboardSpy_Example/Pods-KeyboardSpy_Example-acknowledgements.plist @@ -43,7 +43,7 @@ THE SOFTWARE. FooterText - Copyright (C) 2015 - 2016, Daniel Dahan and CosmicMind, Inc. <http://cosmicmind.com>. All rights reserved. + Copyright (C) 2015 - 2017, Daniel Dahan and CosmicMind, Inc. <http://cosmicmind.com>. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/Example/Pods/Target Support Files/Pods-KeyboardSpy_Example/Pods-KeyboardSpy_Example-frameworks.sh b/Example/Pods/Target Support Files/Pods-KeyboardSpy_Example/Pods-KeyboardSpy_Example-frameworks.sh index 3709ccf..111093a 100755 --- a/Example/Pods/Target Support Files/Pods-KeyboardSpy_Example/Pods-KeyboardSpy_Example-frameworks.sh +++ b/Example/Pods/Target Support Files/Pods-KeyboardSpy_Example/Pods-KeyboardSpy_Example-frameworks.sh @@ -6,6 +6,10 @@ mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" +# This protects against multiple targets copying the same framework dependency at the same time. The solution +# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html +RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") + install_framework() { if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then @@ -23,9 +27,9 @@ install_framework() 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}" + # Use filter instead of exclude so missing patterns don't throw errors. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" local basename basename="$(basename -s .framework "$1")" @@ -54,13 +58,27 @@ install_framework() fi } +# Copies the dSYM of a vendored framework +install_dsym() { + local source="$1" + if [ -r "$source" ]; then + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DWARF_DSYM_FOLDER_PATH}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DWARF_DSYM_FOLDER_PATH}" + fi +} + # Signs a framework with the provided identity code_sign_if_enabled() { if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then # 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} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements \"$1\"" - /usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements "$1" + local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements '$1'" + + if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then + code_sign_cmd="$code_sign_cmd &" + fi + echo "$code_sign_cmd" + eval "$code_sign_cmd" fi } @@ -71,7 +89,7 @@ strip_invalid_archs() { archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)" stripped="" for arch in $archs; do - if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then + if ! [[ "${ARCHS}" == *"$arch"* ]]; then # Strip non-valid architectures in-place lipo -remove "$arch" -output "$binary" "$binary" || exit 1 stripped="$stripped $arch" @@ -84,12 +102,15 @@ strip_invalid_archs() { if [[ "$CONFIGURATION" == "Debug" ]]; then - install_framework "$BUILT_PRODUCTS_DIR/KeyboardSpy/KeyboardSpy.framework" - install_framework "$BUILT_PRODUCTS_DIR/Material/Material.framework" - install_framework "$BUILT_PRODUCTS_DIR/SnapKit/SnapKit.framework" + install_framework "${BUILT_PRODUCTS_DIR}/KeyboardSpy/KeyboardSpy.framework" + install_framework "${BUILT_PRODUCTS_DIR}/Material/Material.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SnapKit/SnapKit.framework" fi if [[ "$CONFIGURATION" == "Release" ]]; then - install_framework "$BUILT_PRODUCTS_DIR/KeyboardSpy/KeyboardSpy.framework" - install_framework "$BUILT_PRODUCTS_DIR/Material/Material.framework" - install_framework "$BUILT_PRODUCTS_DIR/SnapKit/SnapKit.framework" + install_framework "${BUILT_PRODUCTS_DIR}/KeyboardSpy/KeyboardSpy.framework" + install_framework "${BUILT_PRODUCTS_DIR}/Material/Material.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SnapKit/SnapKit.framework" +fi +if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then + wait fi diff --git a/Example/Pods/Target Support Files/Pods-KeyboardSpy_Example/Pods-KeyboardSpy_Example-resources.sh b/Example/Pods/Target Support Files/Pods-KeyboardSpy_Example/Pods-KeyboardSpy_Example-resources.sh index 25e9d37..a7df440 100755 --- a/Example/Pods/Target Support Files/Pods-KeyboardSpy_Example/Pods-KeyboardSpy_Example-resources.sh +++ b/Example/Pods/Target Support Files/Pods-KeyboardSpy_Example/Pods-KeyboardSpy_Example-resources.sh @@ -8,6 +8,10 @@ RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt XCASSET_FILES=() +# This protects against multiple targets copying the same framework dependency at the same time. The solution +# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html +RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") + case "${TARGETED_DEVICE_FAMILY}" in 1,2) TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" @@ -18,6 +22,12 @@ case "${TARGETED_DEVICE_FAMILY}" in 2) TARGET_DEVICE_ARGS="--target-device ipad" ;; + 3) + TARGET_DEVICE_ARGS="--target-device tv" + ;; + 4) + TARGET_DEVICE_ARGS="--target-device watch" + ;; *) TARGET_DEVICE_ARGS="--target-device mac" ;; @@ -38,29 +48,29 @@ EOM fi case $RESOURCE_PATH in *.storyboard) - echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" + echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} ;; *.xib) - echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" + echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} ;; *.framework) - echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" - echo "rsync -av $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" - rsync -av "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" ;; *.xcdatamodel) - echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" + echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" || true xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" ;; *.xcdatamodeld) - echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" + echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" || true xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" ;; *.xcmappingmodel) - echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" + echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" || true xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" ;; *.xcassets) @@ -68,7 +78,7 @@ EOM XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") ;; *) - echo "$RESOURCE_PATH" + echo "$RESOURCE_PATH" || true echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" ;; esac diff --git a/Example/Pods/Target Support Files/Pods-KeyboardSpy_Example/Pods-KeyboardSpy_Example-umbrella.h b/Example/Pods/Target Support Files/Pods-KeyboardSpy_Example/Pods-KeyboardSpy_Example-umbrella.h index 3766f68..25e2330 100644 --- a/Example/Pods/Target Support Files/Pods-KeyboardSpy_Example/Pods-KeyboardSpy_Example-umbrella.h +++ b/Example/Pods/Target Support Files/Pods-KeyboardSpy_Example/Pods-KeyboardSpy_Example-umbrella.h @@ -1,5 +1,13 @@ #ifdef __OBJC__ #import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif #endif diff --git a/Example/Pods/Target Support Files/Pods-KeyboardSpy_Example/Pods-KeyboardSpy_Example.debug.xcconfig b/Example/Pods/Target Support Files/Pods-KeyboardSpy_Example/Pods-KeyboardSpy_Example.debug.xcconfig index 9f9d972..d2adad7 100644 --- a/Example/Pods/Target Support Files/Pods-KeyboardSpy_Example/Pods-KeyboardSpy_Example.debug.xcconfig +++ b/Example/Pods/Target Support Files/Pods-KeyboardSpy_Example/Pods-KeyboardSpy_Example.debug.xcconfig @@ -1,5 +1,4 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES -EMBEDDED_CONTENT_CONTAINS_SWIFT = YES FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/KeyboardSpy" "$PODS_CONFIGURATION_BUILD_DIR/Material" "$PODS_CONFIGURATION_BUILD_DIR/SnapKit" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' @@ -8,4 +7,5 @@ OTHER_LDFLAGS = $(inherited) -framework "KeyboardSpy" -framework "Material" -fra OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" PODS_BUILD_DIR = $BUILD_DIR PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_PODFILE_DIR_PATH = ${SRCROOT}/. PODS_ROOT = ${SRCROOT}/Pods diff --git a/Example/Pods/Target Support Files/Pods-KeyboardSpy_Example/Pods-KeyboardSpy_Example.release.xcconfig b/Example/Pods/Target Support Files/Pods-KeyboardSpy_Example/Pods-KeyboardSpy_Example.release.xcconfig index 9f9d972..d2adad7 100644 --- a/Example/Pods/Target Support Files/Pods-KeyboardSpy_Example/Pods-KeyboardSpy_Example.release.xcconfig +++ b/Example/Pods/Target Support Files/Pods-KeyboardSpy_Example/Pods-KeyboardSpy_Example.release.xcconfig @@ -1,5 +1,4 @@ ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES -EMBEDDED_CONTENT_CONTAINS_SWIFT = YES FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/KeyboardSpy" "$PODS_CONFIGURATION_BUILD_DIR/Material" "$PODS_CONFIGURATION_BUILD_DIR/SnapKit" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' @@ -8,4 +7,5 @@ OTHER_LDFLAGS = $(inherited) -framework "KeyboardSpy" -framework "Material" -fra OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" PODS_BUILD_DIR = $BUILD_DIR PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_PODFILE_DIR_PATH = ${SRCROOT}/. PODS_ROOT = ${SRCROOT}/Pods diff --git a/Example/Pods/Target Support Files/SnapKit/Info.plist b/Example/Pods/Target Support Files/SnapKit/Info.plist index c11c2ee..3424ca6 100644 --- a/Example/Pods/Target Support Files/SnapKit/Info.plist +++ b/Example/Pods/Target Support Files/SnapKit/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 3.1.2 + 4.0.0 CFBundleSignature ???? CFBundleVersion diff --git a/Example/Pods/Target Support Files/SnapKit/SnapKit-prefix.pch b/Example/Pods/Target Support Files/SnapKit/SnapKit-prefix.pch index aa992a4..beb2a24 100644 --- a/Example/Pods/Target Support Files/SnapKit/SnapKit-prefix.pch +++ b/Example/Pods/Target Support Files/SnapKit/SnapKit-prefix.pch @@ -1,4 +1,12 @@ #ifdef __OBJC__ #import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif #endif diff --git a/Example/Pods/Target Support Files/SnapKit/SnapKit-umbrella.h b/Example/Pods/Target Support Files/SnapKit/SnapKit-umbrella.h index 832d727..1b1be64 100644 --- a/Example/Pods/Target Support Files/SnapKit/SnapKit-umbrella.h +++ b/Example/Pods/Target Support Files/SnapKit/SnapKit-umbrella.h @@ -1,5 +1,13 @@ #ifdef __OBJC__ #import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif #endif diff --git a/Example/Pods/Target Support Files/SnapKit/SnapKit.xcconfig b/Example/Pods/Target Support Files/SnapKit/SnapKit.xcconfig index e6ea1b4..3fe6941 100644 --- a/Example/Pods/Target Support Files/SnapKit/SnapKit.xcconfig +++ b/Example/Pods/Target Support Files/SnapKit/SnapKit.xcconfig @@ -5,5 +5,6 @@ OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" PODS_BUILD_DIR = $BUILD_DIR PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/SnapKit PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} SKIP_INSTALL = YES diff --git a/KeyboardSpy.podspec b/KeyboardSpy.podspec index 71c6efb..a022d8b 100644 --- a/KeyboardSpy.podspec +++ b/KeyboardSpy.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = 'KeyboardSpy' - s.version = '1.0' + s.version = '1.1' s.summary = 'The Easiest Way to Observe Keyboard Notifications in iOS' s.description = 'KeyboardSpy is a super lightweight and easy to use wrapper that makes observing keyboard notifications in iOS a breeze.' s.homepage = 'https://github.com/Daltron/KeyboardSpy' diff --git a/KeyboardSpy/Classes/KeyboardSpy.swift b/KeyboardSpy/Classes/KeyboardSpy.swift index deff3f7..3c4efd7 100644 --- a/KeyboardSpy/Classes/KeyboardSpy.swift +++ b/KeyboardSpy/Classes/KeyboardSpy.swift @@ -56,27 +56,27 @@ public class KeyboardSpy { object: nil) } - private dynamic func keyboardWillShow(notification: Notification) { + @objc private dynamic func keyboardWillShow(notification: Notification) { processKeyboardEvent(.willShow, notification: notification) } - private dynamic func keyboardDidShow(notification: Notification) { + @objc private dynamic func keyboardDidShow(notification: Notification) { processKeyboardEvent(.didShow, notification: notification) } - private dynamic func keyboardWillHide(notification: Notification) { + @objc private dynamic func keyboardWillHide(notification: Notification) { processKeyboardEvent(.willHide, notification: notification) } - private dynamic func keyboardDidHide(notification: Notification) { + @objc private dynamic func keyboardDidHide(notification: Notification) { processKeyboardEvent(.didHide, notification: notification) } - private dynamic func keyboardWillChangeFrame(notification: Notification) { + @objc private dynamic func keyboardWillChangeFrame(notification: Notification) { processKeyboardEvent(.willChangeFrame, notification: notification) } - private dynamic func keyboardDidChangeFrame(notification: Notification) { + @objc private dynamic func keyboardDidChangeFrame(notification: Notification) { processKeyboardEvent(.didChangeFrame, notification: notification) } diff --git a/KeyboardSpy/Classes/KeyboardSpyAgent.swift b/KeyboardSpy/Classes/KeyboardSpyAgent.swift index c888e35..dee526d 100644 --- a/KeyboardSpy/Classes/KeyboardSpyAgent.swift +++ b/KeyboardSpy/Classes/KeyboardSpyAgent.swift @@ -18,7 +18,7 @@ */ public protocol KeyboardSpyAgent { - var keyboardEventsToSpyOn: [KeyboardSpyEvent] { get set } + var keyboardEventsToSpyOn: [KeyboardSpyEvent] { get } func keyboardSpyEventProcessed(event:KeyboardSpyEvent, keyboardInfo: KeyboardSpyInfo) var description: String { get } } diff --git a/README.md b/README.md index 39fcde8..e6d3fcf 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,18 @@ ![KeyboardSpy](https://raw.githubusercontent.com/Daltron/KeyboardSpy/master/KeyboardSpy/Assets/keyboard_spy.png) [![Version](https://img.shields.io/cocoapods/v/Spartan.svg?style=flat)](http://cocoapods.org/pods/KeyboardSpy) -Language: Swift +Language: Swift [![Platform](https://img.shields.io/cocoapods/p/KeyboardSpy.svg?style=flat)](http://cocoapods.org/pods/KeyboardSpy) [![License](https://img.shields.io/cocoapods/l/KeyboardSpy.svg?style=flat)](http://cocoapods.org/pods/KeyboardSpy) -### Written in Swift 3 +### Written in Swift 4 KeyboardSpy is a super lightweight and easy to use wrapper that makes observing keyboard notifications in iOS a breeze. ## Requirements - iOS 8.0+ - - xCode 8.1+ + - xCode 9.0+ ## Installation @@ -21,10 +21,6 @@ KeyboardSpy is a super lightweight and easy to use wrapper that makes observing To integrate KeyboardSpy into your xCode project using CocoaPods, specify it in your `Podfile`: ```ruby -source 'https://github.com/CocoaPods/Specs.git' -platform :ios, '8.0' -use_frameworks! - pod 'KeyboardSpy' ``` @@ -40,7 +36,7 @@ KeyboardSpy uses a protocol based approach to observe keyboard notifications: ```swift public protocol KeyboardSpyAgent { - var keyboardEventsToSpyOn: [KeyboardSpyEvent] { get set } + var keyboardEventsToSpyOn: [KeyboardSpyEvent] { get } func keyboardSpyEventProcessed(event:KeyboardSpyEvent, keyboardInfo: KeyboardSpyInfo) } ``` @@ -88,9 +84,7 @@ public class KeyboardSpyInfo: NSObject { ```swift import KeyboardSpy -class KeyboardSpyViewController: UIViewController, KeyboardSpyAgent { - - internal var keyboardEventsToSpyOn: [KeyboardSpyEvent] = [.willShow, .willHide] +class KeyboardSpyViewController: UIViewController { override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) @@ -102,14 +96,22 @@ class KeyboardSpyViewController: UIViewController, KeyboardSpyAgent { KeyboardSpy.unspy(on: keyboardSpyView) // This can be placed anywhere } - func keyboardSpyEventProcessed(event: KeyboardSpyEvent, keyboardInfo: KeyboardSpyInfo) { +} + +extension KeyboardSpyViewController: KeyboardSpyAgent { + + internal var keyboardEventsToSpyOn: [KeyboardSpyEvent] { + return [.willShow, .willHide] + } + + internal func keyboardSpyEventProcessed(event: KeyboardSpyEvent, keyboardInfo: KeyboardSpyInfo) { if event == .willShow { // Do something like moving a view above the keyboard } else if event == .willHide { // Do something like moving a view back to its original position } } - + } ```