├── .DS_Store ├── MMPullSwipeDismiss.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── mukesh.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── mukesh.xcuserdatad │ └── xcschemes │ └── xcschememanagement.plist ├── MMPullSwipeDismiss.xcworkspace ├── contents.xcworkspacedata └── xcuserdata │ └── mukesh.xcuserdatad │ ├── UserInterfaceState.xcuserstate │ └── xcdebugger │ └── Breakpoints_v2.xcbkptlist ├── MMPullSwipeDismiss ├── AppDelegate.swift ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── Controller │ ├── MMPullSwipeDismissViewController.swift │ └── ViewController.swift ├── Extension │ ├── PanExUtil.swift │ ├── PullSwipeExUtil.swift │ └── ScrollViewExUtil.swift ├── Info.plist ├── demomaster_swipealeft.gif ├── demomaster_swipebup.gif └── demomaster_swipedown.gif ├── MMPullSwipeDismissTests ├── Info.plist └── MMPullSwipeDismissTests.swift ├── MMPullSwipeDismissUITests ├── Info.plist └── MMPullSwipeDismissUITests.swift ├── Podfile ├── Podfile.lock ├── Pods ├── Hero │ ├── LICENSE │ ├── README.md │ └── Sources │ │ ├── Animator │ │ ├── HeroAnimatorViewContext.swift │ │ ├── HeroCoreAnimationViewContext.swift │ │ ├── HeroDefaultAnimator.swift │ │ └── HeroViewPropertyViewContext.swift │ │ ├── Debug Plugin │ │ ├── HeroDebugPlugin.swift │ │ └── HeroDebugView.swift │ │ ├── Extensions │ │ ├── Array+HeroModifier.swift │ │ ├── CALayer+Hero.swift │ │ ├── CAMediaTimingFunction+Hero.swift │ │ ├── CG+Hero.swift │ │ ├── DispatchQueue+Hero.swift │ │ ├── UIKit+Hero.swift │ │ ├── UIView+Hero.swift │ │ └── UIViewController+Hero.swift │ │ ├── HeroContext.swift │ │ ├── HeroModifier+HeroStringConvertible.swift │ │ ├── HeroModifier.swift │ │ ├── HeroPlugin.swift │ │ ├── HeroTargetState.swift │ │ ├── HeroTypes.swift │ │ ├── HeroViewControllerDelegate.swift │ │ ├── Parser │ │ ├── HeroStringConvertible.swift │ │ ├── Lexer.swift │ │ ├── Nodes.swift │ │ ├── Parser.swift │ │ └── Regex.swift │ │ ├── Preprocessors │ │ ├── BasePreprocessor.swift │ │ ├── CascadePreprocessor.swift │ │ ├── ConditionalPreprocessor.swift │ │ ├── DefaultAnimationPreprocessor.swift │ │ ├── IgnoreSubviewModifiersPreprocessor.swift │ │ ├── MatchPreprocessor.swift │ │ └── SourcePreprocessor.swift │ │ └── Transition │ │ ├── HeroProgressRunner.swift │ │ ├── HeroTransition+Animate.swift │ │ ├── HeroTransition+Complete.swift │ │ ├── HeroTransition+CustomTransition.swift │ │ ├── HeroTransition+Interactive.swift │ │ ├── HeroTransition+Start.swift │ │ ├── HeroTransition+UINavigationControllerDelegate.swift │ │ ├── HeroTransition+UITabBarControllerDelegate.swift │ │ ├── HeroTransition+UIViewControllerTransitioningDelegate.swift │ │ ├── HeroTransition.swift │ │ └── HeroTransitionState.swift ├── Local Podspecs │ └── Hero.podspec.json ├── Manifest.lock ├── Pods.xcodeproj │ ├── project.pbxproj │ └── xcuserdata │ │ └── mukesh.xcuserdatad │ │ └── xcschemes │ │ ├── Hero.xcscheme │ │ ├── Pods-MMPullSwipeDismiss.xcscheme │ │ ├── Pods-MMPullSwipeDismissTests.xcscheme │ │ ├── Pods-MMPullSwipeDismissUITests.xcscheme │ │ └── xcschememanagement.plist └── Target Support Files │ ├── Hero │ ├── Hero-dummy.m │ ├── Hero-prefix.pch │ ├── Hero-umbrella.h │ ├── Hero.modulemap │ ├── Hero.xcconfig │ └── Info.plist │ ├── Pods-MMPullSwipeDismiss │ ├── Info.plist │ ├── Pods-MMPullSwipeDismiss-acknowledgements.markdown │ ├── Pods-MMPullSwipeDismiss-acknowledgements.plist │ ├── Pods-MMPullSwipeDismiss-dummy.m │ ├── Pods-MMPullSwipeDismiss-frameworks.sh │ ├── Pods-MMPullSwipeDismiss-resources.sh │ ├── Pods-MMPullSwipeDismiss-umbrella.h │ ├── Pods-MMPullSwipeDismiss.debug.xcconfig │ ├── Pods-MMPullSwipeDismiss.modulemap │ └── Pods-MMPullSwipeDismiss.release.xcconfig │ ├── Pods-MMPullSwipeDismissTests │ ├── Info.plist │ ├── Pods-MMPullSwipeDismissTests-acknowledgements.markdown │ ├── Pods-MMPullSwipeDismissTests-acknowledgements.plist │ ├── Pods-MMPullSwipeDismissTests-dummy.m │ ├── Pods-MMPullSwipeDismissTests-frameworks.sh │ ├── Pods-MMPullSwipeDismissTests-resources.sh │ ├── Pods-MMPullSwipeDismissTests-umbrella.h │ ├── Pods-MMPullSwipeDismissTests.debug.xcconfig │ ├── Pods-MMPullSwipeDismissTests.modulemap │ └── Pods-MMPullSwipeDismissTests.release.xcconfig │ └── Pods-MMPullSwipeDismissUITests │ ├── Info.plist │ ├── Pods-MMPullSwipeDismissUITests-acknowledgements.markdown │ ├── Pods-MMPullSwipeDismissUITests-acknowledgements.plist │ ├── Pods-MMPullSwipeDismissUITests-dummy.m │ ├── Pods-MMPullSwipeDismissUITests-frameworks.sh │ ├── Pods-MMPullSwipeDismissUITests-resources.sh │ ├── Pods-MMPullSwipeDismissUITests-umbrella.h │ ├── Pods-MMPullSwipeDismissUITests.debug.xcconfig │ ├── Pods-MMPullSwipeDismissUITests.modulemap │ └── Pods-MMPullSwipeDismissUITests.release.xcconfig └── README.md /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mukyasa/MMPullSwipeDismiss/a9ead516298a0d2cc6ef1dbc9f6446704c3f6377/.DS_Store -------------------------------------------------------------------------------- /MMPullSwipeDismiss.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /MMPullSwipeDismiss.xcodeproj/project.xcworkspace/xcuserdata/mukesh.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mukyasa/MMPullSwipeDismiss/a9ead516298a0d2cc6ef1dbc9f6446704c3f6377/MMPullSwipeDismiss.xcodeproj/project.xcworkspace/xcuserdata/mukesh.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /MMPullSwipeDismiss.xcodeproj/xcuserdata/mukesh.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | MMPullSwipeDismiss.xcscheme 8 | 9 | orderHint 10 | 4 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /MMPullSwipeDismiss.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /MMPullSwipeDismiss.xcworkspace/xcuserdata/mukesh.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mukyasa/MMPullSwipeDismiss/a9ead516298a0d2cc6ef1dbc9f6446704c3f6377/MMPullSwipeDismiss.xcworkspace/xcuserdata/mukesh.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /MMPullSwipeDismiss.xcworkspace/xcuserdata/mukesh.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /MMPullSwipeDismiss/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // MMPullSwipeDismiss 4 | // 5 | // Created by Mukesh on 03/11/17. 6 | // Copyright © 2017 Mad Apps. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(_ application: UIApplication) { 23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 24 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 25 | } 26 | 27 | func applicationDidEnterBackground(_ application: UIApplication) { 28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | func applicationWillEnterForeground(_ application: UIApplication) { 33 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | func applicationDidBecomeActive(_ application: UIApplication) { 37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 38 | } 39 | 40 | func applicationWillTerminate(_ application: UIApplication) { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /MMPullSwipeDismiss/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /MMPullSwipeDismiss/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /MMPullSwipeDismiss/Controller/MMPullSwipeDismissViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MMPullSwipeDismissViewController.swift 3 | // MMPullSwipeDismiss 4 | // 5 | // Created by Mukesh on 03/11/17. 6 | // Copyright © 2017 Mad Apps. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import Hero 11 | 12 | class MMPullSwipeDismissViewController: UITableViewController { 13 | 14 | var panGR : UIPanGestureRecognizer! 15 | var progressBool : Bool = false 16 | var dismissBool : Bool = true 17 | 18 | override func viewDidLoad() { 19 | 20 | super.viewDidLoad() 21 | // Do any additional setup after loading the view, typically from a nib 22 | 23 | panGR = UIPanGestureRecognizer(target: self, action: #selector(pan)) 24 | 25 | /* 26 | Add navbar to controller through storyboard and replace the selector method with panWithNavbar 27 | 28 | */ 29 | // panGR = UIPanGestureRecognizer(target: self, action: #selector(panWithNavbar)) 30 | 31 | panGR.delegate = self 32 | 33 | view.backgroundColor = UIColor.white 34 | view.addGestureRecognizer(panGR) 35 | tableView.bouncesZoom = false 36 | 37 | headerView() 38 | 39 | 40 | } 41 | 42 | func headerView(){ 43 | let header = UIView(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: 84)) 44 | 45 | let button:UIButton = UIButton(frame: CGRect(x: 20, y: 10, width: 50, height: 40)) 46 | button.setTitle("Back", for: .normal) 47 | button.titleLabel?.textAlignment = .left 48 | button.setTitleColor(UIColor.blue, for: .normal) 49 | button.addTarget(self, action:#selector(dismissVc), for: .touchUpInside) 50 | header.addSubview(button) 51 | 52 | let label = UILabel(frame: CGRect(x: 20, y: 50, width: 300, height: 44)) 53 | label.text = "Your Detail Page" 54 | label.font = UIFont.boldSystemFont(ofSize: 30) 55 | header.addSubview(label) 56 | 57 | tableView.tableHeaderView = header 58 | } 59 | 60 | @objc func dismissVc(){ 61 | hero_dismissViewController() 62 | } 63 | 64 | 65 | 66 | override func didReceiveMemoryWarning() { 67 | super.didReceiveMemoryWarning() 68 | // Dispose of any resources that can be recreated. 69 | } 70 | 71 | 72 | 73 | } 74 | 75 | 76 | extension MMPullSwipeDismissViewController : UIGestureRecognizerDelegate { 77 | 78 | func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool{ 79 | 80 | return true 81 | } 82 | } 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /MMPullSwipeDismiss/Controller/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // MMPullSwipeDismiss 4 | // 5 | // Created by Mukesh on 03/11/17. 6 | // Copyright © 2017 Mad Apps. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ViewController: UIViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | // Do any additional setup after loading the view, typically from a nib. 16 | if #available(iOS 11.0, *) { 17 | self.navigationController?.navigationBar.prefersLargeTitles = true 18 | } else { 19 | // Fallback on earlier versions 20 | } 21 | } 22 | 23 | override func didReceiveMemoryWarning() { 24 | super.didReceiveMemoryWarning() 25 | // Dispose of any resources that can be recreated. 26 | } 27 | 28 | @IBAction func goToDetailAction(_ sender: Any) { 29 | let story = UIStoryboard(name: "Main", bundle: nil) 30 | let vc = story.instantiateViewController(withIdentifier: "detail") 31 | vc.modalPresentationStyle = .overCurrentContext 32 | vc.isHeroEnabled = true 33 | vc.heroModalAnimationType = .selectBy(presenting: .cover(direction: .left), dismissing: .uncover(direction: .right)) 34 | self.present(vc, animated: true, completion: nil) 35 | } 36 | 37 | } 38 | 39 | -------------------------------------------------------------------------------- /MMPullSwipeDismiss/Extension/PanExUtil.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PanExUtil.swift 3 | // MMPullSwipeDismiss 4 | // 5 | // Created by Mukesh on 04/11/17. 6 | // Copyright © 2017 Mad Apps. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | //Pan Gesture 12 | public enum PanDirection: Int { 13 | case up, down, left, right 14 | public var isVertical: Bool { return [.up, .down].contains(self) } 15 | public var isHorizontal: Bool { return !isVertical } 16 | } 17 | 18 | public extension UIPanGestureRecognizer { 19 | 20 | public var direction: PanDirection? { 21 | let velocity = self.velocity(in: view) 22 | let isVertical = fabs(velocity.y) > fabs(velocity.x) 23 | switch (isVertical, velocity.x, velocity.y) { 24 | case (true, _, let y) where y < 0: return .up 25 | case (true, _, let y) where y > 0: return .down 26 | case (false, let x, _) where x > 0: return .right 27 | case (false, let x, _) where x < 0: return .left 28 | default: return nil 29 | } 30 | 31 | } 32 | 33 | } 34 | 35 | -------------------------------------------------------------------------------- /MMPullSwipeDismiss/Extension/ScrollViewExUtil.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ScrollViewExUtil.swift 3 | // MMPullSwipeDismiss 4 | // 5 | // Created by Mukesh on 04/11/17. 6 | // Copyright © 2017 Mad Apps. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | public extension UIScrollView { 12 | 13 | var isAtTop: Bool { 14 | return contentOffset.y <= verticalOffsetForTop 15 | } 16 | 17 | var isAtBottom: Bool { 18 | return contentOffset.y >= verticalOffsetForBottom 19 | } 20 | 21 | var verticalOffsetForTop: CGFloat { 22 | let topInset = contentInset.top 23 | return -topInset 24 | } 25 | 26 | var verticalOffsetForBottom: CGFloat { 27 | let scrollViewHeight = bounds.height 28 | let scrollContentSizeHeight = contentSize.height 29 | let bottomInset = contentInset.bottom 30 | let scrollViewBottomOffset = scrollContentSizeHeight + bottomInset - scrollViewHeight 31 | return scrollViewBottomOffset 32 | } 33 | 34 | } 35 | 36 | -------------------------------------------------------------------------------- /MMPullSwipeDismiss/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /MMPullSwipeDismiss/demomaster_swipealeft.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mukyasa/MMPullSwipeDismiss/a9ead516298a0d2cc6ef1dbc9f6446704c3f6377/MMPullSwipeDismiss/demomaster_swipealeft.gif -------------------------------------------------------------------------------- /MMPullSwipeDismiss/demomaster_swipebup.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mukyasa/MMPullSwipeDismiss/a9ead516298a0d2cc6ef1dbc9f6446704c3f6377/MMPullSwipeDismiss/demomaster_swipebup.gif -------------------------------------------------------------------------------- /MMPullSwipeDismiss/demomaster_swipedown.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mukyasa/MMPullSwipeDismiss/a9ead516298a0d2cc6ef1dbc9f6446704c3f6377/MMPullSwipeDismiss/demomaster_swipedown.gif -------------------------------------------------------------------------------- /MMPullSwipeDismissTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /MMPullSwipeDismissTests/MMPullSwipeDismissTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MMPullSwipeDismissTests.swift 3 | // MMPullSwipeDismissTests 4 | // 5 | // Created by Mukesh on 03/11/17. 6 | // Copyright © 2017 Mad Apps. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import MMPullSwipeDismiss 11 | 12 | class MMPullSwipeDismissTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | // This is an example of a functional test case. 26 | // Use XCTAssert and related functions to verify your tests produce the correct results. 27 | } 28 | 29 | func testPerformanceExample() { 30 | // This is an example of a performance test case. 31 | self.measure { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /MMPullSwipeDismissUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /MMPullSwipeDismissUITests/MMPullSwipeDismissUITests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MMPullSwipeDismissUITests.swift 3 | // MMPullSwipeDismissUITests 4 | // 5 | // Created by Mukesh on 03/11/17. 6 | // Copyright © 2017 Mad Apps. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class MMPullSwipeDismissUITests: XCTestCase { 12 | 13 | override func setUp() { 14 | super.setUp() 15 | 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | 18 | // In UI tests it is usually best to stop immediately when a failure occurs. 19 | continueAfterFailure = false 20 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 21 | XCUIApplication().launch() 22 | 23 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 24 | } 25 | 26 | override func tearDown() { 27 | // Put teardown code here. This method is called after the invocation of each test method in the class. 28 | super.tearDown() 29 | } 30 | 31 | func testExample() { 32 | // Use recording to get started writing UI tests. 33 | // Use XCTAssert and related functions to verify your tests produce the correct results. 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment the next line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | target 'MMPullSwipeDismiss' do 5 | # Comment the next line if you're not using Swift and don't want to use dynamic frameworks 6 | use_frameworks! 7 | pod 'Hero', :git => 'https://github.com/lkzhao/Hero.git' 8 | 9 | # Pods for MMPullSwipeDismiss 10 | 11 | target 'MMPullSwipeDismissTests' do 12 | inherit! :search_paths 13 | # Pods for testing 14 | end 15 | 16 | target 'MMPullSwipeDismissUITests' do 17 | inherit! :search_paths 18 | # Pods for testing 19 | end 20 | 21 | end 22 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Hero (1.0.0) 3 | 4 | DEPENDENCIES: 5 | - Hero (from `https://github.com/lkzhao/Hero.git`) 6 | 7 | EXTERNAL SOURCES: 8 | Hero: 9 | :git: https://github.com/lkzhao/Hero.git 10 | 11 | CHECKOUT OPTIONS: 12 | Hero: 13 | :commit: 5a9302c6ebdb1c36adb49d0803e61d5d0c9c5a91 14 | :git: https://github.com/lkzhao/Hero.git 15 | 16 | SPEC CHECKSUMS: 17 | Hero: a0481f995d78951544614a8e828f7eb374e73c06 18 | 19 | PODFILE CHECKSUM: 3cabcfd2218ed3e7f52e3046e9b9f10881ee4222 20 | 21 | COCOAPODS: 1.2.1 22 | -------------------------------------------------------------------------------- /Pods/Hero/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Luke Zhao 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /Pods/Hero/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | **Hero** is a library for building iOS view controller transitions. It provides a declarative layer on top of the UIKit's cumbersome transition APIs—making custom transitions an easy task for developers. 4 | 5 | [![Carthage compatible](https://img.shields.io/badge/Carthage-Compatible-brightgreen.svg?style=flat)](https://github.com/Carthage/Carthage) 6 | [![Version](https://img.shields.io/cocoapods/v/Hero.svg?style=flat)](http://cocoapods.org/pods/Hero) 7 | [![License](https://img.shields.io/cocoapods/l/Hero.svg?style=flat)](https://github.com/lkzhao/Hero/blob/master/LICENSE?raw=true) 8 | ![Xcode 9.0+](https://img.shields.io/badge/Xcode-9.0%2B-blue.svg) 9 | ![iOS 8.0+](https://img.shields.io/badge/iOS-8.0%2B-blue.svg) 10 | ![Swift 4.0+](https://img.shields.io/badge/Swift-4.0%2B-orange.svg) 11 | [![中文 README](https://img.shields.io/badge/%E4%B8%AD%E6%96%87-README-blue.svg?style=flat)](https://github.com/lkzhao/Hero/blob/master/README.zh-cn.md) 12 | [![Donate](https://img.shields.io/badge/Donate-PayPal-blue.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=NT5F7Y2MPV7RE) 13 | 14 |        15 | 16 | 17 | Hero is similar to Keynote's **Magic Move**. It checks the `heroID` property on all source and destination views. Every matched view pair is then automatically transitioned from its old state to its new state. 18 | 19 | Hero can also construct animations for unmatched views. It is easy to define these animations via the `heroModifiers` property. Hero will run these animations alongside the **Magic Move** animations. All of these animations can be **interactively controlled** by user gestures. 20 | 21 | At view controller level, Hero provides several template transitions that you can set through `heroModalAnimationType`, `heroNavigationAnimationType`, and `heroTabBarAnimationType`. These can be used as the foundation of your custom transitions. Combine with `heroID` & `heroModifiers` to make your own unique transitions. 22 | 23 |        24 | 25 | 26 | By default, Hero provides **dynamic duration** based on the [Material Design Motion Guide](https://material.io/guidelines/motion/duration-easing.html). Duration is automatically determined by changes to distance and size—saving you the hassle, while providing consistent and delightful animations. 27 | 28 | Hero doesn't make any assumptions about how the view is built or structured. It won't modify any of your views' states other than hiding them during the animation. This makes it work with **Auto Layout**, **programmatic layout**, **UICollectionView** (without modifying its layout object), **UITableView**, **UINavigationController**, **UITabBarController**, etc... 29 | 30 | 31 | ## Example Gallery 32 | 33 | Checkout the [Example Gallery Blog Post](http://lkzhao.com/2016/12/28/hero.html) for a general idea of what you can achieve with **Hero** 34 | 35 | ## Usage Example 1 36 | 37 | 38 | 39 | ##### View Controller 1 40 | ```swift 41 | redView.heroID = "ironMan" 42 | blackView.heroID = "batMan" 43 | ``` 44 | 45 | ##### View Controller 2 46 | ```swift 47 | isHeroEnabled = true 48 | redView.heroID = "ironMan" 49 | blackView.heroID = "batMan" 50 | whiteView.heroModifiers = [.translate(y:100)] 51 | ``` 52 | 53 | 54 | ## Usage Example 2 55 | 56 | 57 | ##### View Controller 1 58 | ```swift 59 | greyView.heroID = "skyWalker" 60 | ``` 61 | 62 | ##### View Controller 2 63 | ```swift 64 | isHeroEnabled = true 65 | greyView.heroID = "skyWalker" 66 | 67 | // collectionView is the parent view of all red cells 68 | collectionView.heroModifiers = [.cascade] 69 | for cell in redCells { 70 | cell.heroModifiers = [.fade, .scale(0.5)] 71 | } 72 | ``` 73 | 74 | You can do these in the **storyboard** too! 75 | 76 | 77 | 78 | 79 | ## Documentations 80 | 81 | Checkout the **[WIKI PAGES (Usage Guide)](https://github.com/lkzhao/Hero/wiki/Usage-Guide)** for documentations. 82 | 83 | For more up-to-date ones, please see the header-doc. (use **alt+click** in Xcode) 84 | 85 | 86 | ## Interactive Transition Tutorials 87 | 88 | [Interactive transitions with Hero (Part 1)](http://lkzhao.com/2017/02/05/hero-interactive-transition.html) 89 | 90 | ## FAQ 91 | 92 | #### White flashes occurs on iPhone 7 (Plus) Simulators 93 | 94 | Hero **does not work** on iPhone 7 (Plus) Simulators due to an [Apple bug](https://forums.developer.apple.com/thread/63438). Please use other simulators or a real device when working with Hero. 95 | 96 | #### Not able to use Hero transition even when `isHeroEnabled` is set to true 97 | 98 | Make sure that you have also enabled `isHeroEnabled` on the navigation controller if you are doing a push/pop inside the navigation controller. 99 | 100 | #### Views being covered by another matched view during the transition 101 | 102 | Matched views use global coordinate space while unmatched views use local coordinate space by default. Local coordinate spaced views might be covered by other global coordinate spaced views. To solve this, use the `useGlobalCoordinateSpace` modifier on the views being covered. Checkout [Coordinate Space Wiki page](https://github.com/lkzhao/Hero/wiki/Coordinate-Space) for details. 103 | 104 | #### Weird behavior with UIVisualEffectView 105 | 106 | UIVisualEffectView is quite hard to animate due to its private implementation and incompatibility with `snapshotAfterScreenUpdate` and some Core Animation APIs. We are trying to get these solved as much as we can. Currently, as of 0.3.2, only unmatched UIVisualEffectView with noninteractive `.fade` animation is supported. 107 | 108 | #### Push animation is shown along side my custom animation 109 | 110 | This is the default animation for navigation controller provided by Hero. To disable the push animation, set `heroNavigationAnimationType` to `.fade` or `.none` on the navigation controller. 111 | 112 | #### How do I use a different default animation when dismissing 113 | 114 | You can use the animation type `.selectBy(presenting:dismissing)` to specify a different default animation for dismiss. 115 | 116 | For example: 117 | 118 | ```swift 119 | heroModalAnimationType = .selectBy(presenting:.zoom, dismissing:.zoomOut) 120 | ``` 121 | 122 | ## Contribute 123 | 124 | We welcome any contributions. Please read the [Contribution Guide](https://github.com/lkzhao/Hero/wiki/Contribution-Guide). 125 | -------------------------------------------------------------------------------- /Pods/Hero/Sources/Animator/HeroAnimatorViewContext.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2016 Luke Zhao 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | internal class HeroAnimatorViewContext { 26 | weak var animator: HeroAnimator? 27 | let snapshot: UIView 28 | let appearing: Bool 29 | var targetState: HeroTargetState 30 | var duration: TimeInterval = 0 31 | 32 | // computed 33 | var currentTime: TimeInterval { 34 | return snapshot.layer.convertTime(CACurrentMediaTime(), from: nil) 35 | } 36 | var container: UIView? { 37 | return animator?.hero.context.container 38 | } 39 | 40 | class func canAnimate(view: UIView, state: HeroTargetState, appearing: Bool) -> Bool { 41 | return false 42 | } 43 | 44 | func apply(state: HeroTargetState) { 45 | } 46 | 47 | func resume(timePassed: TimeInterval, reverse: Bool) -> TimeInterval { 48 | return 0 49 | } 50 | 51 | func seek(timePassed: TimeInterval) { 52 | } 53 | 54 | func clean() { 55 | animator = nil 56 | } 57 | 58 | func startAnimations() -> TimeInterval { 59 | return 0 60 | } 61 | 62 | required init(animator: HeroAnimator, snapshot: UIView, targetState: HeroTargetState, appearing: Bool) { 63 | self.animator = animator 64 | self.snapshot = snapshot 65 | self.targetState = targetState 66 | self.appearing = appearing 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /Pods/Hero/Sources/Animator/HeroDefaultAnimator.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2016 Luke Zhao 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | internal extension UIView { 26 | func optimizedDurationTo(position: CGPoint?, size: CGSize?, transform: CATransform3D?) -> TimeInterval { 27 | let fromPos = (layer.presentation() ?? layer).position 28 | let toPos = position ?? fromPos 29 | let fromSize = (layer.presentation() ?? layer).bounds.size 30 | let toSize = size ?? fromSize 31 | let fromTransform = (layer.presentation() ?? layer).transform 32 | let toTransform = transform ?? fromTransform 33 | 34 | let realFromPos = CGPoint.zero.transform(fromTransform) + fromPos 35 | let realToPos = CGPoint.zero.transform(toTransform) + toPos 36 | 37 | let realFromSize = fromSize.transform(fromTransform) 38 | let realToSize = toSize.transform(toTransform) 39 | 40 | let movePoints = (realFromPos.distance(realToPos) + realFromSize.point.distance(realToSize.point)) 41 | 42 | // duration is 0.2 @ 0 to 0.375 @ 500 43 | let duration = 0.208 + Double(movePoints.clamp(0, 500)) / 3000 44 | return duration 45 | } 46 | } 47 | 48 | internal class HeroDefaultAnimator: HeroAnimator { 49 | weak public var hero: HeroTransition! 50 | public var context: HeroContext! { 51 | return hero?.context 52 | } 53 | var viewContexts: [UIView: ViewContext] = [:] 54 | 55 | public func seekTo(timePassed: TimeInterval) { 56 | for viewContext in viewContexts.values { 57 | viewContext.seek(timePassed: timePassed) 58 | } 59 | } 60 | 61 | public func resume(timePassed: TimeInterval, reverse: Bool) -> TimeInterval { 62 | var duration: TimeInterval = 0 63 | for (_, viewContext) in viewContexts { 64 | if viewContext.targetState.duration == nil { 65 | viewContext.duration = max(viewContext.duration, 66 | calculateOptimizedDuration(snapshot: viewContext.snapshot, 67 | targetState: viewContext.targetState) + timePassed) 68 | } 69 | let timeUntilStopped = viewContext.resume(timePassed: timePassed, reverse: reverse) 70 | duration = max(duration, timeUntilStopped) 71 | } 72 | return duration 73 | } 74 | 75 | public func apply(state: HeroTargetState, to view: UIView) { 76 | if let context = viewContexts[view] { 77 | context.apply(state:state) 78 | } 79 | } 80 | 81 | public func canAnimate(view: UIView, appearing: Bool) -> Bool { 82 | guard let state = context[view] else { return false } 83 | return ViewContext.canAnimate(view: view, state: state, appearing: appearing) 84 | } 85 | 86 | public func animate(fromViews: [UIView], toViews: [UIView]) -> TimeInterval { 87 | var maxDuration: TimeInterval = 0 88 | 89 | for v in fromViews { createViewContext(view: v, appearing: false) } 90 | for v in toViews { createViewContext(view: v, appearing: true) } 91 | 92 | for viewContext in viewContexts.values { 93 | if let duration = viewContext.targetState.duration, duration != .infinity { 94 | viewContext.duration = duration 95 | maxDuration = max(maxDuration, duration) 96 | } else { 97 | let duration = calculateOptimizedDuration(snapshot: viewContext.snapshot, targetState: viewContext.targetState) 98 | if viewContext.targetState.duration == nil { 99 | viewContext.duration = duration 100 | } 101 | maxDuration = max(maxDuration, duration) 102 | } 103 | } 104 | for viewContext in viewContexts.values { 105 | if viewContext.targetState.duration == .infinity { 106 | viewContext.duration = maxDuration 107 | } 108 | let timeUntilStopped = viewContext.startAnimations() 109 | maxDuration = max(maxDuration, timeUntilStopped) 110 | } 111 | 112 | return maxDuration 113 | } 114 | 115 | func calculateOptimizedDuration(snapshot: UIView, targetState: HeroTargetState) -> TimeInterval { 116 | return snapshot.optimizedDurationTo(position: targetState.position, 117 | size: targetState.size, 118 | transform: targetState.transform) 119 | } 120 | 121 | func createViewContext(view: UIView, appearing: Bool) { 122 | let snapshot = context.snapshotView(for: view) 123 | let viewContext = ViewContext(animator:self, snapshot: snapshot, targetState: context[view]!, appearing: appearing) 124 | viewContexts[view] = viewContext 125 | } 126 | 127 | public func clean() { 128 | for vc in viewContexts.values { 129 | vc.clean() 130 | } 131 | viewContexts.removeAll() 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /Pods/Hero/Sources/Animator/HeroViewPropertyViewContext.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2016 Luke Zhao 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | @available(iOS 10, tvOS 10, *) 26 | internal class HeroViewPropertyViewContext: HeroAnimatorViewContext { 27 | 28 | var viewPropertyAnimator: UIViewPropertyAnimator! 29 | var endEffect: UIVisualEffect? 30 | var startEffect: UIVisualEffect? 31 | 32 | override class func canAnimate(view: UIView, state: HeroTargetState, appearing: Bool) -> Bool { 33 | return view is UIVisualEffectView && state.opacity != nil 34 | } 35 | 36 | override func resume(timePassed: TimeInterval, reverse: Bool) -> TimeInterval { 37 | guard let visualEffectView = snapshot as? UIVisualEffectView else { return 0 } 38 | if reverse { 39 | viewPropertyAnimator?.stopAnimation(false) 40 | viewPropertyAnimator?.finishAnimation(at: .current) 41 | viewPropertyAnimator = UIViewPropertyAnimator(duration: duration, curve: .linear) { 42 | visualEffectView.effect = reverse ? self.startEffect : self.endEffect 43 | } 44 | } 45 | viewPropertyAnimator.startAnimation() 46 | return duration 47 | } 48 | 49 | override func seek(timePassed: TimeInterval) { 50 | viewPropertyAnimator?.pauseAnimation() 51 | viewPropertyAnimator?.fractionComplete = CGFloat(timePassed / duration) 52 | } 53 | 54 | override func clean() { 55 | super.clean() 56 | viewPropertyAnimator?.stopAnimation(false) 57 | viewPropertyAnimator?.finishAnimation(at: .current) 58 | viewPropertyAnimator = nil 59 | } 60 | 61 | override func startAnimations() -> TimeInterval { 62 | guard let visualEffectView = snapshot as? UIVisualEffectView else { return 0 } 63 | let appearedEffect = visualEffectView.effect 64 | let disappearedEffect = targetState.opacity == 0 ? nil : visualEffectView.effect 65 | startEffect = appearing ? disappearedEffect : appearedEffect 66 | endEffect = appearing ? appearedEffect : disappearedEffect 67 | visualEffectView.effect = startEffect 68 | viewPropertyAnimator = UIViewPropertyAnimator(duration: duration, curve: .linear) { 69 | visualEffectView.effect = self.endEffect 70 | } 71 | viewPropertyAnimator.startAnimation() 72 | return duration 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Pods/Hero/Sources/Debug Plugin/HeroDebugPlugin.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2016 Luke Zhao 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | #if os(iOS) 26 | public class HeroDebugPlugin: HeroPlugin { 27 | public static var showOnTop: Bool = false 28 | 29 | var debugView: HeroDebugView? 30 | var zPositionMap = [UIView: CGFloat]() 31 | var addedLayers: [CALayer] = [] 32 | var updating = false 33 | 34 | override public func animate(fromViews: [UIView], toViews: [UIView]) -> TimeInterval { 35 | if hero.forceNotInteractive { return 0 } 36 | var hasArc = false 37 | for v in context.fromViews + context.toViews where context[v]?.arc != nil && context[v]?.position != nil { 38 | hasArc = true 39 | break 40 | } 41 | let debugView = HeroDebugView(initialProcess: hero.isPresenting ? 0.0 : 1.0, showCurveButton:hasArc, showOnTop:HeroDebugPlugin.showOnTop) 42 | debugView.frame = hero.container.bounds 43 | debugView.delegate = self 44 | hero.container.window?.addSubview(debugView) 45 | 46 | debugView.layoutSubviews() 47 | self.debugView = debugView 48 | 49 | UIView.animate(withDuration: 0.4) { 50 | debugView.showControls = true 51 | } 52 | 53 | return .infinity 54 | } 55 | 56 | public override func resume(timePassed: TimeInterval, reverse: Bool) -> TimeInterval { 57 | guard let debugView = debugView else { return 0.4 } 58 | debugView.delegate = nil 59 | 60 | UIView.animate(withDuration: 0.4) { 61 | debugView.showControls = false 62 | debugView.debugSlider.setValue(roundf(debugView.progress), animated: true) 63 | } 64 | 65 | on3D(wants3D: false) 66 | return 0.4 67 | } 68 | 69 | public override func clean() { 70 | debugView?.removeFromSuperview() 71 | debugView = nil 72 | } 73 | } 74 | 75 | extension HeroDebugPlugin:HeroDebugViewDelegate { 76 | public func onDone() { 77 | guard let debugView = debugView else { return } 78 | let seekValue = hero.isPresenting ? debugView.progress : 1.0 - debugView.progress 79 | if seekValue > 0.5 { 80 | hero.finish() 81 | } else { 82 | hero.cancel() 83 | } 84 | } 85 | 86 | public func onProcessSliderChanged(progress: Float) { 87 | let seekValue = hero.isPresenting ? progress : 1.0 - progress 88 | hero.update(CGFloat(seekValue)) 89 | } 90 | 91 | func onPerspectiveChanged(translation: CGPoint, rotation: CGFloat, scale: CGFloat) { 92 | var t = CATransform3DIdentity 93 | t.m34 = -1 / 4000 94 | t = CATransform3DTranslate(t, translation.x, translation.y, 0) 95 | t = CATransform3DScale(t, scale, scale, 1) 96 | t = CATransform3DRotate(t, rotation, 0, 1, 0) 97 | hero.container.layer.sublayerTransform = t 98 | } 99 | 100 | func animateZPosition(view: UIView, to: CGFloat) { 101 | let a = CABasicAnimation(keyPath: "zPosition") 102 | a.fromValue = view.layer.value(forKeyPath: "zPosition") 103 | a.toValue = NSNumber(value: Double(to)) 104 | a.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut) 105 | a.duration = 0.4 106 | view.layer.add(a, forKey: "zPosition") 107 | view.layer.zPosition = to 108 | } 109 | 110 | func onDisplayArcCurve(wantsCurve: Bool) { 111 | for layer in addedLayers { 112 | layer.removeFromSuperlayer() 113 | addedLayers.removeAll() 114 | } 115 | if wantsCurve { 116 | for layer in hero.container.layer.sublayers! { 117 | for (_, anim) in layer.animations { 118 | if let keyframeAnim = anim as? CAKeyframeAnimation, let path = keyframeAnim.path { 119 | let s = CAShapeLayer() 120 | s.zPosition = layer.zPosition + 10 121 | s.path = path 122 | s.strokeColor = UIColor.blue.cgColor 123 | s.fillColor = UIColor.clear.cgColor 124 | hero.container.layer.addSublayer(s) 125 | addedLayers.append(s) 126 | } 127 | } 128 | } 129 | } 130 | } 131 | 132 | func on3D(wants3D: Bool) { 133 | var t = CATransform3DIdentity 134 | if wants3D { 135 | var viewsWithZPosition = Set() 136 | for view in hero.container.subviews where view.layer.zPosition != 0 { 137 | viewsWithZPosition.insert(view) 138 | zPositionMap[view] = view.layer.zPosition 139 | } 140 | 141 | let viewsWithoutZPosition = hero.container.subviews.filter { return !viewsWithZPosition.contains($0) } 142 | let viewsWithPositiveZPosition = viewsWithZPosition.filter { return $0.layer.zPosition > 0 } 143 | 144 | for (i, v) in viewsWithoutZPosition.enumerated() { 145 | animateZPosition(view:v, to:CGFloat(i * 10)) 146 | } 147 | 148 | var maxZPosition: CGFloat = 0 149 | for v in viewsWithPositiveZPosition { 150 | maxZPosition = max(maxZPosition, v.layer.zPosition) 151 | animateZPosition(view:v, to:v.layer.zPosition + CGFloat(viewsWithoutZPosition.count * 10)) 152 | } 153 | 154 | t.m34 = -1 / 4000 155 | t = CATransform3DTranslate(t, debugView!.translation.x, debugView!.translation.y, 0) 156 | t = CATransform3DScale(t, debugView!.scale, debugView!.scale, 1) 157 | t = CATransform3DRotate(t, debugView!.rotation, 0, 1, 0) 158 | } else { 159 | for v in hero.container.subviews { 160 | animateZPosition(view:v, to:self.zPositionMap[v] ?? 0) 161 | } 162 | self.zPositionMap.removeAll() 163 | } 164 | 165 | let a = CABasicAnimation(keyPath: "sublayerTransform") 166 | a.fromValue = hero.container.layer.value(forKeyPath: "sublayerTransform") 167 | a.toValue = NSValue(caTransform3D: t) 168 | a.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut) 169 | a.duration = 0.4 170 | 171 | UIView.animate(withDuration:0.4) { 172 | self.context.container.backgroundColor = UIColor(white: 0.85, alpha: 1.0) 173 | } 174 | 175 | hero.container.layer.add(a, forKey: "debug") 176 | hero.container.layer.sublayerTransform = t 177 | } 178 | } 179 | #endif 180 | -------------------------------------------------------------------------------- /Pods/Hero/Sources/Extensions/Array+HeroModifier.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2016 Luke Zhao 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | internal extension Array { 26 | func get(_ index: Int) -> Element? { 27 | if index < count { 28 | return self[index] 29 | } 30 | return nil 31 | } 32 | } 33 | 34 | internal extension Array where Element: ExprNode { 35 | func getCGFloat(_ index: Int) -> CGFloat? { 36 | if let s = get(index) as? NumberNode { 37 | return CGFloat(s.value) 38 | } 39 | return nil 40 | } 41 | func getDouble(_ index: Int) -> Double? { 42 | if let s = get(index) as? NumberNode { 43 | return Double(s.value) 44 | } 45 | return nil 46 | } 47 | func getFloat(_ index: Int) -> Float? { 48 | if let s = get(index) as? NumberNode { 49 | return s.value 50 | } 51 | return nil 52 | } 53 | func getBool(_ index: Int) -> Bool? { 54 | if let s = get(index) as? VariableNode, let f = Bool(s.name) { 55 | return f 56 | } 57 | return nil 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Pods/Hero/Sources/Extensions/CALayer+Hero.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2016 Luke Zhao 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | internal extension CALayer { 26 | // return all animations running by this layer. 27 | // the returned value is mutable 28 | var animations: [(String, CAAnimation)] { 29 | if let keys = animationKeys() { 30 | return keys.map { return ($0, self.animation(forKey: $0)!.copy() as! CAAnimation) } 31 | } 32 | return [] 33 | } 34 | 35 | func flatTransformTo(layer: CALayer) -> CATransform3D { 36 | var layer = layer 37 | var trans = layer.transform 38 | while let superlayer = layer.superlayer, superlayer != self { 39 | trans = CATransform3DConcat(superlayer.transform, trans) 40 | layer = superlayer 41 | } 42 | return trans 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Pods/Hero/Sources/Extensions/CAMediaTimingFunction+Hero.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2016 Luke Zhao 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | public extension CAMediaTimingFunction { 26 | // default 27 | public static let linear = CAMediaTimingFunction(name: kCAMediaTimingFunctionLinear) 28 | public static let easeIn = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseIn) 29 | public static let easeOut = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut) 30 | public static let easeInOut = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut) 31 | 32 | // material 33 | public static let standard = CAMediaTimingFunction(controlPoints: 0.4, 0.0, 0.2, 1.0) 34 | public static let deceleration = CAMediaTimingFunction(controlPoints: 0.0, 0.0, 0.2, 1) 35 | public static let acceleration = CAMediaTimingFunction(controlPoints: 0.4, 0.0, 1, 1) 36 | public static let sharp = CAMediaTimingFunction(controlPoints: 0.4, 0.0, 0.6, 1) 37 | 38 | // easing.net 39 | public static let easeOutBack = CAMediaTimingFunction(controlPoints: 0.175, 0.885, 0.32, 1.275) 40 | 41 | static func from(name: String) -> CAMediaTimingFunction? { 42 | switch name { 43 | case "linear": 44 | return .linear 45 | case "easeIn": 46 | return .easeIn 47 | case "easeOut": 48 | return .easeOut 49 | case "easeInOut": 50 | return .easeInOut 51 | case "standard": 52 | return .standard 53 | case "deceleration": 54 | return .deceleration 55 | case "acceleration": 56 | return .acceleration 57 | case "sharp": 58 | return .sharp 59 | default: 60 | return nil 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Pods/Hero/Sources/Extensions/CG+Hero.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2016 Luke Zhao 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import MetalKit 24 | 25 | let π = CGFloat.pi 26 | 27 | internal struct KeySet { 28 | var dict: [Key:Set] = [:] 29 | internal subscript(key: Key) -> Set { 30 | mutating get { 31 | if dict[key] == nil { 32 | dict[key] = Set() 33 | } 34 | return dict[key]! 35 | } 36 | set { 37 | dict[key] = newValue 38 | } 39 | } 40 | } 41 | 42 | internal extension CGSize { 43 | internal var center: CGPoint { 44 | return CGPoint(x: width / 2, y: height / 2) 45 | } 46 | internal var point: CGPoint { 47 | return CGPoint(x: width, y: height) 48 | } 49 | internal func transform(_ t: CGAffineTransform) -> CGSize { 50 | return self.applying(t) 51 | } 52 | internal func transform(_ t: CATransform3D) -> CGSize { 53 | return self.applying(CATransform3DGetAffineTransform(t)) 54 | } 55 | } 56 | 57 | internal extension CGRect { 58 | internal var center: CGPoint { 59 | return CGPoint(x: origin.x + size.width/2, y: origin.y + size.height/2) 60 | } 61 | internal var bounds: CGRect { 62 | return CGRect(origin: CGPoint.zero, size: size) 63 | } 64 | init(center: CGPoint, size: CGSize) { 65 | self.init(x: center.x - size.width/2, y: center.y - size.height/2, width: size.width, height: size.height) 66 | } 67 | } 68 | 69 | extension CGFloat { 70 | internal func clamp(_ a: CGFloat, _ b: CGFloat) -> CGFloat { 71 | return self < a ? a : (self > b ? b : self) 72 | } 73 | } 74 | extension TimeInterval { 75 | internal func clamp(_ a: TimeInterval, _ b: TimeInterval) -> TimeInterval { 76 | return self < a ? a : (self > b ? b : self) 77 | } 78 | } 79 | extension CGPoint { 80 | internal func translate(_ dx: CGFloat, dy: CGFloat) -> CGPoint { 81 | return CGPoint(x: self.x+dx, y: self.y+dy) 82 | } 83 | 84 | internal func transform(_ t: CGAffineTransform) -> CGPoint { 85 | return self.applying(t) 86 | } 87 | 88 | internal func transform(_ t: CATransform3D) -> CGPoint { 89 | return self.applying(CATransform3DGetAffineTransform(t)) 90 | } 91 | 92 | internal func distance(_ b: CGPoint) -> CGFloat { 93 | return sqrt(pow(self.x - b.x, 2) + pow(self.y - b.y, 2)) 94 | } 95 | } 96 | 97 | internal func + (left: CGPoint, right: CGPoint) -> CGPoint { 98 | return CGPoint(x: left.x + right.x, y: left.y + right.y) 99 | } 100 | 101 | internal func - (left: CGPoint, right: CGPoint) -> CGPoint { 102 | return CGPoint(x: left.x - right.x, y: left.y - right.y) 103 | } 104 | 105 | internal func / (left: CGPoint, right: CGFloat) -> CGPoint { 106 | return CGPoint(x: left.x/right, y: left.y/right) 107 | } 108 | internal func / (left: CGPoint, right: CGPoint) -> CGPoint { 109 | return CGPoint(x: left.x/right.x, y: left.y/right.y) 110 | } 111 | internal func * (left: CGPoint, right: CGFloat) -> CGPoint { 112 | return CGPoint(x: left.x*right, y: left.y*right) 113 | } 114 | internal func * (left: CGPoint, right: CGSize) -> CGPoint { 115 | return CGPoint(x: left.x*right.width, y: left.y*right.width) 116 | } 117 | internal func * (left: CGFloat, right: CGPoint) -> CGPoint { 118 | return right * left 119 | } 120 | 121 | internal func * (left: CGPoint, right: CGPoint) -> CGPoint { 122 | return CGPoint(x: left.x*right.x, y: left.y*right.y) 123 | } 124 | 125 | internal prefix func - (point: CGPoint) -> CGPoint { 126 | return CGPoint.zero - point 127 | } 128 | 129 | internal func abs(_ p: CGPoint) -> CGPoint { 130 | return CGPoint(x: abs(p.x), y: abs(p.y)) 131 | } 132 | 133 | internal func * (left: CGSize, right: CGFloat) -> CGSize { 134 | return CGSize(width: left.width*right, height: left.height*right) 135 | } 136 | internal func * (left: CGSize, right: CGSize) -> CGSize { 137 | return CGSize(width: left.width*right.width, height: left.height*right.height) 138 | } 139 | internal func / (left: CGSize, right: CGSize) -> CGSize { 140 | return CGSize(width: left.width/right.width, height: left.height/right.height) 141 | } 142 | 143 | internal func == (lhs: CATransform3D, rhs: CATransform3D) -> Bool { 144 | var lhs = lhs 145 | var rhs = rhs 146 | return memcmp(&lhs, &rhs, MemoryLayout.size) == 0 147 | } 148 | 149 | internal func != (lhs: CATransform3D, rhs: CATransform3D) -> Bool { 150 | return !(lhs == rhs) 151 | } 152 | -------------------------------------------------------------------------------- /Pods/Hero/Sources/Extensions/DispatchQueue+Hero.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2016 Luke Zhao 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import Foundation 24 | 25 | func delay(_ time: Double, execute: @escaping () -> Void) { 26 | if time > 0 { 27 | DispatchQueue.main.asyncAfter(deadline: .now() + time, execute: execute) 28 | } else { 29 | DispatchQueue.main.async(execute: execute) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Pods/Hero/Sources/Extensions/UIKit+Hero.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2016 Luke Zhao 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | private let parameterRegex = "(?:\\-?\\d+(\\.?\\d+)?)|\\w+" 26 | private let modifiersRegex = "(\\w+)(?:\\(([^\\)]*)\\))?" 27 | 28 | internal extension NSObject { 29 | func copyWithArchiver() -> Any? { 30 | return NSKeyedUnarchiver.unarchiveObject(with: NSKeyedArchiver.archivedData(withRootObject: self))! 31 | } 32 | } 33 | 34 | internal extension UIImage { 35 | class func imageWithView(view: UIView) -> UIImage { 36 | UIGraphicsBeginImageContextWithOptions(view.bounds.size, false, 0.0) 37 | view.drawHierarchy(in: view.bounds, afterScreenUpdates: true) 38 | let img = UIGraphicsGetImageFromCurrentImageContext() 39 | UIGraphicsEndImageContext() 40 | return img! 41 | } 42 | } 43 | 44 | internal extension UIColor { 45 | var components:(r:CGFloat, g: CGFloat, b: CGFloat, a: CGFloat) { 46 | var r: CGFloat = 0 47 | var g: CGFloat = 0 48 | var b: CGFloat = 0 49 | var a: CGFloat = 0 50 | getRed(&r, green: &g, blue: &b, alpha: &a) 51 | return (r, g, b, a) 52 | } 53 | var alphaComponent: CGFloat { 54 | return components.a 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /Pods/Hero/Sources/Extensions/UIView+Hero.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2016 Luke Zhao 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | class SnapshotWrapperView: UIView { 26 | let contentView: UIView 27 | init(contentView: UIView) { 28 | self.contentView = contentView 29 | super.init(frame: contentView.frame) 30 | addSubview(contentView) 31 | } 32 | required init?(coder aDecoder: NSCoder) { 33 | fatalError("init(coder:) has not been implemented") 34 | } 35 | override func layoutSubviews() { 36 | super.layoutSubviews() 37 | contentView.bounds.size = bounds.size 38 | contentView.center = bounds.center 39 | } 40 | } 41 | 42 | public extension UIView { 43 | private struct AssociatedKeys { 44 | static var heroID = "heroID" 45 | static var heroModifiers = "heroModifers" 46 | static var heroStoredAlpha = "heroStoredAlpha" 47 | static var heroEnabled = "heroEnabled" 48 | static var heroEnabledForSubviews = "heroEnabledForSubviews" 49 | } 50 | 51 | /** 52 | **heroID** is the identifier for the view. When doing a transition between two view controllers, 53 | Hero will search through all the subviews for both view controllers and matches views with the same **heroID**. 54 | 55 | Whenever a pair is discovered, 56 | Hero will automatically transit the views from source state to the destination state. 57 | */ 58 | @IBInspectable public var heroID: String? { 59 | get { return objc_getAssociatedObject(self, &AssociatedKeys.heroID) as? String } 60 | set { objc_setAssociatedObject(self, &AssociatedKeys.heroID, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) } 61 | } 62 | 63 | /** 64 | **isHeroEnabled** allows to specify whether a view and its subviews should be consider for animations. 65 | If true, Hero will search through all the subviews for heroIds and modifiers. Defaults to true 66 | */ 67 | @IBInspectable public var isHeroEnabled: Bool { 68 | get { return objc_getAssociatedObject(self, &AssociatedKeys.heroEnabled) as? Bool ?? true } 69 | set { objc_setAssociatedObject(self, &AssociatedKeys.heroEnabled, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) } 70 | } 71 | 72 | /** 73 | **isHeroEnabledForSubviews** allows to specify whether a view's subviews should be consider for animations. 74 | If true, Hero will search through all the subviews for heroIds and modifiers. Defaults to true 75 | */ 76 | @IBInspectable public var isHeroEnabledForSubviews: Bool { 77 | get { return objc_getAssociatedObject(self, &AssociatedKeys.heroEnabledForSubviews) as? Bool ?? true } 78 | set { objc_setAssociatedObject(self, &AssociatedKeys.heroEnabledForSubviews, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) } 79 | } 80 | 81 | /** 82 | Use **heroModifiers** to specify animations alongside the main transition. Checkout `HeroModifier.swift` for available modifiers. 83 | */ 84 | public var heroModifiers: [HeroModifier]? { 85 | get { return objc_getAssociatedObject(self, &AssociatedKeys.heroModifiers) as? [HeroModifier] } 86 | set { objc_setAssociatedObject(self, &AssociatedKeys.heroModifiers, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) } 87 | } 88 | 89 | /** 90 | **heroModifierString** provides another way to set **heroModifiers**. It can be assigned through storyboard. 91 | */ 92 | @IBInspectable public var heroModifierString: String? { 93 | get { fatalError("Reverse lookup is not supported") } 94 | set { heroModifiers = newValue?.parse() } 95 | } 96 | 97 | internal func slowSnapshotView() -> UIView { 98 | UIGraphicsBeginImageContextWithOptions(bounds.size, isOpaque, 0) 99 | layer.render(in: UIGraphicsGetCurrentContext()!) 100 | 101 | let image = UIGraphicsGetImageFromCurrentImageContext() 102 | UIGraphicsEndImageContext() 103 | 104 | let imageView = UIImageView(image: image) 105 | imageView.frame = bounds 106 | return SnapshotWrapperView(contentView: imageView) 107 | } 108 | 109 | internal func snapshotView() -> UIView? { 110 | let snapshot = snapshotView(afterScreenUpdates: true) 111 | if #available(iOS 11.0, *), let oldSnapshot = snapshot { 112 | // in iOS 11, the snapshot taken by snapshotView(afterScreenUpdates) won't contain a container view 113 | return SnapshotWrapperView(contentView: oldSnapshot) 114 | } else { 115 | return snapshot 116 | } 117 | } 118 | 119 | internal var flattenedViewHierarchy: [UIView] { 120 | guard isHeroEnabled else { return [] } 121 | if #available(iOS 9.0, *), isHidden && (superview is UICollectionView || superview is UIStackView || self is UITableViewCell) { 122 | return [] 123 | } else if isHidden && (superview is UICollectionView || self is UITableViewCell) { 124 | return [] 125 | } else if isHeroEnabledForSubviews { 126 | return [self] + subviews.flatMap { $0.flattenedViewHierarchy } 127 | } else { 128 | return [self] 129 | } 130 | } 131 | 132 | /// Used for .overFullScreen presentation 133 | internal var heroStoredAlpha: CGFloat? { 134 | get { 135 | if let doubleValue = (objc_getAssociatedObject(self, &AssociatedKeys.heroStoredAlpha) as? NSNumber)?.doubleValue { 136 | return CGFloat(doubleValue) 137 | } 138 | return nil 139 | } 140 | set { 141 | if let newValue = newValue { 142 | objc_setAssociatedObject(self, &AssociatedKeys.heroStoredAlpha, NSNumber(value:newValue.native), .OBJC_ASSOCIATION_RETAIN_NONATOMIC) 143 | } else { 144 | objc_setAssociatedObject(self, &AssociatedKeys.heroStoredAlpha, nil, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) 145 | } 146 | } 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /Pods/Hero/Sources/HeroModifier+HeroStringConvertible.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2016 Luke Zhao 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | /// used to construct HeroModifier from heroModifierString 26 | extension HeroModifier: HeroStringConvertible { 27 | public static func from(node: ExprNode) -> HeroModifier? { 28 | let name: String = node.name 29 | let parameters: [ExprNode] = (node as? CallNode)?.arguments ?? [] 30 | 31 | switch name { 32 | case "fade": 33 | return .fade 34 | case "opacity": 35 | return HeroModifier.opacity(CGFloat(parameters.getFloat(0) ?? 1)) 36 | case "position": 37 | return .position(CGPoint(x: parameters.getCGFloat(0) ?? 0, y: parameters.getCGFloat(1) ?? 0)) 38 | case "size": 39 | return .size(CGSize(width: parameters.getCGFloat(0) ?? 0, height: parameters.getCGFloat(1) ?? 0)) 40 | case "scale": 41 | if parameters.count == 1 { 42 | return .scale(parameters.getCGFloat(0) ?? 1) 43 | } else { 44 | return .scale(x: parameters.getCGFloat(0) ?? 1, 45 | y: parameters.getCGFloat(1) ?? 1, 46 | z: parameters.getCGFloat(2) ?? 1) 47 | } 48 | case "rotate": 49 | if parameters.count == 1 { 50 | return .rotate(parameters.getCGFloat(0) ?? 0) 51 | } else { 52 | return .rotate(x: parameters.getCGFloat(0) ?? 0, 53 | y: parameters.getCGFloat(1) ?? 0, 54 | z: parameters.getCGFloat(2) ?? 0) 55 | } 56 | case "translate": 57 | return .translate(x: parameters.getCGFloat(0) ?? 0, 58 | y: parameters.getCGFloat(1) ?? 0, 59 | z: parameters.getCGFloat(2) ?? 0) 60 | case "overlay": 61 | return .overlay(color: UIColor(red: parameters.getCGFloat(0) ?? 1, 62 | green: parameters.getCGFloat(1) ?? 1, 63 | blue: parameters.getCGFloat(2) ?? 1, 64 | alpha: 1), 65 | opacity: parameters.getCGFloat(3) ?? 1) 66 | case "duration": 67 | if let duration = parameters.getDouble(0) { 68 | return .duration(duration) 69 | } 70 | case "durationMatchLongest": 71 | return .durationMatchLongest 72 | case "delay": 73 | if let delay = parameters.getDouble(0) { 74 | return .delay(delay) 75 | } 76 | case "spring": 77 | if #available(iOS 9, *) { 78 | return .spring(stiffness: parameters.getCGFloat(0) ?? 250, damping: parameters.getCGFloat(1) ?? 30) 79 | } 80 | case "timingFunction": 81 | if let c1 = parameters.getFloat(0), 82 | let c2 = parameters.getFloat(1), 83 | let c3 = parameters.getFloat(2), 84 | let c4 = parameters.getFloat(3) { 85 | return .timingFunction(CAMediaTimingFunction(controlPoints: c1, c2, c3, c4)) 86 | } else if let name = parameters.get(0)?.name, let timingFunction = CAMediaTimingFunction.from(name:name) { 87 | return .timingFunction(timingFunction) 88 | } 89 | case "arc": 90 | return .arc(intensity: parameters.getCGFloat(0) ?? 1) 91 | case "cascade": 92 | var cascadeDirection = CascadeDirection.topToBottom 93 | if let directionString = parameters.get(1)?.name, 94 | let direction = CascadeDirection(directionString) { 95 | cascadeDirection = direction 96 | } 97 | return .cascade(delta: parameters.getDouble(0) ?? 0.02, direction: cascadeDirection, delayMatchedViews:parameters.getBool(2) ?? false) 98 | case "source": 99 | if let heroID = parameters.get(0)?.name { 100 | return .source(heroID: heroID) 101 | } 102 | case "useGlobalCoordinateSpace": 103 | return .useGlobalCoordinateSpace 104 | case "ignoreSubviewModifiers": 105 | return .ignoreSubviewModifiers(recursive:parameters.getBool(0) ?? false) 106 | case "zPosition": 107 | if let zPosition = parameters.getCGFloat(0) { 108 | return .zPosition(zPosition) 109 | } 110 | case "useOptimizedSnapshot": 111 | return .useOptimizedSnapshot 112 | case "useNormalSnapshot": 113 | return .useNormalSnapshot 114 | case "useLayerRenderSnapshot": 115 | return .useLayerRenderSnapshot 116 | case "useNoSnapshot": 117 | return .useNoSnapshot 118 | case "forceAnimate": 119 | return .forceAnimate 120 | default: break 121 | } 122 | return nil 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /Pods/Hero/Sources/HeroPlugin.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2016 Luke Zhao 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | open class HeroPlugin: NSObject, HeroPreprocessor, HeroAnimator { 26 | 27 | weak public var hero: HeroTransition! 28 | 29 | public var context: HeroContext! { 30 | return hero.context 31 | } 32 | 33 | /** 34 | Determines whether or not to receive `seekTo` callback on every frame. 35 | 36 | Default is false. 37 | 38 | When **requirePerFrameCallback** is **false**, the plugin needs to start its own animations inside `animate` & `resume` 39 | The `seekTo` method is only being called during an interactive transition. 40 | 41 | 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` 42 | */ 43 | open var requirePerFrameCallback = false 44 | 45 | public override required init() {} 46 | 47 | /** 48 | Called before any animation. 49 | Override this method when you want to preprocess modifiers for views 50 | - Parameters: 51 | - context: object holding all parsed and changed modifiers, 52 | - fromViews: A flattened list of all views from source ViewController 53 | - toViews: A flattened list of all views from destination ViewController 54 | 55 | To check a view's modifiers: 56 | 57 | context[view] 58 | context[view, "modifierName"] 59 | 60 | To set a view's modifiers: 61 | 62 | context[view] = [("modifier1", ["parameter1"]), ("modifier2", [])] 63 | context[view, "modifier1"] = ["parameter1", "parameter2"] 64 | 65 | */ 66 | open func process(fromViews: [UIView], toViews: [UIView]) {} 67 | 68 | /** 69 | - Returns: return true if the plugin can handle animating the view. 70 | - Parameters: 71 | - context: object holding all parsed and changed modifiers, 72 | - view: the view to check whether or not the plugin can handle the animation 73 | - appearing: true if the view is appearing(i.e. a view in destination ViewController) 74 | If return true, Hero won't animate and won't let any other plugins animate this view. 75 | The view will also be hidden automatically during the animation. 76 | */ 77 | open func canAnimate(view: UIView, appearing: Bool) -> Bool { return false } 78 | 79 | /** 80 | Perform the animation. 81 | 82 | Note: views in `fromViews` & `toViews` are hidden already. Unhide then if you need to take snapshots. 83 | - Parameters: 84 | - context: object holding all parsed and changed modifiers, 85 | - fromViews: A flattened list of all views from source ViewController (filtered by `canAnimate`) 86 | - toViews: A flattened list of all views from destination ViewController (filtered by `canAnimate`) 87 | - Returns: The duration needed to complete the animation 88 | */ 89 | 90 | open func animate(fromViews: [UIView], toViews: [UIView]) -> TimeInterval { return 0 } 91 | 92 | /** 93 | Called when all animations are completed. 94 | 95 | Should perform cleanup and release any reference 96 | */ 97 | open func clean() {} 98 | 99 | /** 100 | For supporting interactive animation only. 101 | 102 | This method is called when an interactive animation is in place 103 | The plugin should pause the animation, and seek to the given progress 104 | - Parameters: 105 | - timePassed: time of the animation to seek to. 106 | */ 107 | open func seekTo(timePassed: TimeInterval) {} 108 | 109 | /** 110 | For supporting interactive animation only. 111 | 112 | This method is called when an interactive animation is ended 113 | The plugin should resume the animation. 114 | - Parameters: 115 | - timePassed: will be the same value since last `seekTo` 116 | - reverse: a boolean value indicating whether or not the animation should reverse 117 | */ 118 | open func resume(timePassed: TimeInterval, reverse: Bool) -> TimeInterval { return 0 } 119 | 120 | /** 121 | For supporting interactive animation only. 122 | 123 | This method is called when user wants to override animation modifiers during an interactive animation 124 | 125 | - Parameters: 126 | - state: the target state to override 127 | - view: the view to override 128 | */ 129 | open func apply(state: HeroTargetState, to view: UIView) {} 130 | } 131 | 132 | // methods for enable/disable the current plugin 133 | extension HeroPlugin { 134 | public static var isEnabled: Bool { 135 | get { 136 | return HeroTransition.isEnabled(plugin: self) 137 | } 138 | set { 139 | if newValue { 140 | enable() 141 | } else { 142 | disable() 143 | } 144 | } 145 | } 146 | public static func enable() { 147 | HeroTransition.enable(plugin: self) 148 | } 149 | public static func disable() { 150 | HeroTransition.disable(plugin: self) 151 | } 152 | } 153 | 154 | // MARK: Plugin Support 155 | internal extension HeroTransition { 156 | static func isEnabled(plugin: HeroPlugin.Type) -> Bool { 157 | return enabledPlugins.index(where: { return $0 == plugin}) != nil 158 | } 159 | 160 | static func enable(plugin: HeroPlugin.Type) { 161 | disable(plugin: plugin) 162 | enabledPlugins.append(plugin) 163 | } 164 | 165 | static func disable(plugin: HeroPlugin.Type) { 166 | if let index = enabledPlugins.index(where: { return $0 == plugin}) { 167 | enabledPlugins.remove(at: index) 168 | } 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /Pods/Hero/Sources/HeroTargetState.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2016 Luke Zhao 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | public enum HeroSnapshotType { 26 | /// Will optimize for different type of views 27 | /// For custom views or views with masking, .optimizedDefault might create snapshots 28 | /// that appear differently than the actual view. 29 | /// In that case, use .normal or .slowRender to disable the optimization 30 | case optimized 31 | 32 | /// snapshotView(afterScreenUpdates:) 33 | case normal 34 | 35 | /// layer.render(in: currentContext) 36 | case layerRender 37 | 38 | /// will not create snapshot. animate the view directly. 39 | /// This will mess up the view hierarchy, therefore, view controllers have to rebuild 40 | /// its view structure after the transition finishes 41 | case noSnapshot 42 | } 43 | 44 | public enum HeroCoordinateSpace { 45 | case global 46 | case local 47 | } 48 | 49 | public struct HeroTargetState { 50 | public var beginState: [HeroModifier]? 51 | public var conditionalModifiers: [((HeroConditionalContext) -> Bool, [HeroModifier])]? 52 | 53 | public var position: CGPoint? 54 | public var size: CGSize? 55 | public var transform: CATransform3D? 56 | public var opacity: Float? 57 | public var cornerRadius: CGFloat? 58 | public var backgroundColor: CGColor? 59 | public var zPosition: CGFloat? 60 | 61 | public var contentsRect: CGRect? 62 | public var contentsScale: CGFloat? 63 | 64 | public var borderWidth: CGFloat? 65 | public var borderColor: CGColor? 66 | 67 | public var shadowColor: CGColor? 68 | public var shadowOpacity: Float? 69 | public var shadowOffset: CGSize? 70 | public var shadowRadius: CGFloat? 71 | public var shadowPath: CGPath? 72 | public var masksToBounds: Bool? 73 | public var displayShadow: Bool = true 74 | 75 | public var overlay: (color: CGColor, opacity: CGFloat)? 76 | 77 | public var spring: (CGFloat, CGFloat)? 78 | public var delay: TimeInterval = 0 79 | public var duration: TimeInterval? 80 | public var timingFunction: CAMediaTimingFunction? 81 | 82 | public var arc: CGFloat? 83 | public var source: String? 84 | public var cascade: (TimeInterval, CascadeDirection, Bool)? 85 | 86 | public var ignoreSubviewModifiers: Bool? 87 | public var coordinateSpace: HeroCoordinateSpace? 88 | public var useScaleBasedSizeChange: Bool? 89 | public var snapshotType: HeroSnapshotType? 90 | 91 | public var nonFade: Bool = false 92 | public var forceAnimate: Bool = false 93 | public var custom: [String:Any]? 94 | 95 | init(modifiers: [HeroModifier]) { 96 | append(contentsOf: modifiers) 97 | } 98 | 99 | public mutating func append(_ modifier: HeroModifier) { 100 | modifier.apply(&self) 101 | } 102 | 103 | public mutating func append(contentsOf modifiers: [HeroModifier]) { 104 | for modifier in modifiers { 105 | modifier.apply(&self) 106 | } 107 | } 108 | 109 | /** 110 | - Returns: custom item for a specific key 111 | */ 112 | public subscript(key: String) -> Any? { 113 | get { 114 | return custom?[key] 115 | } 116 | set { 117 | if custom == nil { 118 | custom = [:] 119 | } 120 | custom![key] = newValue 121 | } 122 | } 123 | } 124 | 125 | extension HeroTargetState: ExpressibleByArrayLiteral { 126 | public init(arrayLiteral elements: HeroModifier...) { 127 | append(contentsOf: elements) 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /Pods/Hero/Sources/HeroTypes.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2016 Luke Zhao 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | public protocol HeroPreprocessor: class { 26 | weak var hero: HeroTransition! { get set } 27 | func process(fromViews: [UIView], toViews: [UIView]) 28 | } 29 | 30 | public protocol HeroAnimator: class { 31 | weak var hero: HeroTransition! { get set } 32 | func canAnimate(view: UIView, appearing: Bool) -> Bool 33 | func animate(fromViews: [UIView], toViews: [UIView]) -> TimeInterval 34 | func clean() 35 | 36 | func seekTo(timePassed: TimeInterval) 37 | func resume(timePassed: TimeInterval, reverse: Bool) -> TimeInterval 38 | func apply(state: HeroTargetState, to view: UIView) 39 | } 40 | 41 | public protocol HeroProgressUpdateObserver: class { 42 | func heroDidUpdateProgress(progress: Double) 43 | } 44 | 45 | public enum HeroViewOrderingStrategy { 46 | case auto, sourceViewOnTop, destinationViewOnTop 47 | } 48 | -------------------------------------------------------------------------------- /Pods/Hero/Sources/HeroViewControllerDelegate.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2016 Luke Zhao 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | @objc public protocol HeroViewControllerDelegate { 26 | @objc optional func heroWillStartAnimatingFrom(viewController: UIViewController) 27 | @objc optional func heroDidEndAnimatingFrom(viewController: UIViewController) 28 | @objc optional func heroDidCancelAnimatingFrom(viewController: UIViewController) 29 | 30 | @objc optional func heroWillStartTransition() 31 | @objc optional func heroDidEndTransition() 32 | @objc optional func heroDidCancelTransition() 33 | 34 | @objc optional func heroWillStartAnimatingTo(viewController: UIViewController) 35 | @objc optional func heroDidEndAnimatingTo(viewController: UIViewController) 36 | @objc optional func heroDidCancelAnimatingTo(viewController: UIViewController) 37 | } 38 | 39 | // delegate helper 40 | internal extension HeroTransition { 41 | func closureProcessForHeroDelegate(vc: T, closure: (HeroViewControllerDelegate) -> Void) { 42 | if let delegate = vc as? HeroViewControllerDelegate { 43 | closure(delegate) 44 | } 45 | 46 | if let navigationController = vc as? UINavigationController, 47 | let delegate = navigationController.topViewController as? HeroViewControllerDelegate { 48 | closure(delegate) 49 | } else if let tabBarController = vc as? UITabBarController, 50 | let delegate = tabBarController.viewControllers?[tabBarController.selectedIndex] as? HeroViewControllerDelegate { 51 | closure(delegate) 52 | } else { 53 | for vc in vc.childViewControllers where vc.isViewLoaded { 54 | self.closureProcessForHeroDelegate(vc: vc, closure: closure) 55 | } 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Pods/Hero/Sources/Parser/HeroStringConvertible.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2016 Luke Zhao 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | public protocol HeroStringConvertible { 26 | static func from(node: ExprNode) -> Self? 27 | } 28 | 29 | extension String { 30 | func parse() -> [T]? { 31 | let lexer = Lexer(input: self) 32 | let parser = Parser(tokens: lexer.tokenize()) 33 | do { 34 | let nodes = try parser.parse() 35 | var results = [T]() 36 | for node in nodes { 37 | if let modifier = T.from(node: node) { 38 | results.append(modifier) 39 | } else { 40 | print("\(node.name) doesn't exist in \(T.self)") 41 | } 42 | } 43 | return results 44 | } catch let error { 45 | print("failed to parse \"\(self)\", error: \(error)") 46 | } 47 | return nil 48 | } 49 | 50 | func parseOne() -> T? { 51 | return parse()?.last 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Pods/Hero/Sources/Parser/Lexer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Lexer.swift 3 | // Kaleidoscope 4 | // 5 | // Created by Matthew Cheok on 15/11/15. 6 | // Copyright © 2015 Matthew Cheok. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | public enum Token { 12 | case identifier(String, CountableRange) 13 | case number(Float, CountableRange) 14 | case parensOpen(CountableRange) 15 | case parensClose(CountableRange) 16 | case comma(CountableRange) 17 | case other(String, CountableRange) 18 | } 19 | 20 | typealias TokenGenerator = (String, CountableRange) -> Token? 21 | let tokenList: [(String, TokenGenerator)] = [ 22 | ("[ \t\n]", { _, _ in nil }), 23 | ("[a-zA-Z][a-zA-Z0-9]*", { .identifier($0, $1) }), 24 | ("\\-?[0-9.]+", { .number(Float($0)!, $1) }), 25 | ("\\(", { .parensOpen($1) }), 26 | ("\\)", { .parensClose($1) }), 27 | (",", { .comma($1) }) 28 | ] 29 | 30 | public class Lexer { 31 | let input: String 32 | public init(input: String) { 33 | self.input = input 34 | } 35 | public func tokenize() -> [Token] { 36 | var tokens = [Token]() 37 | var content = input 38 | 39 | while !content.characters.isEmpty { 40 | var matched = false 41 | 42 | for (pattern, generator) in tokenList { 43 | if let (m, r) = content.match(regex: pattern) { 44 | if let t = generator(m, r) { 45 | tokens.append(t) 46 | } 47 | 48 | content = String(content[content.index(content.startIndex, offsetBy: m.characters.count)...]) 49 | matched = true 50 | break 51 | } 52 | } 53 | 54 | if !matched { 55 | let index = content.index(content.startIndex, offsetBy: 1) 56 | let intIndex = content.distance(from: content.startIndex, to: index) 57 | tokens.append(.other(String(content[.. = 0..<0 13 | public let name: String 14 | public var description: String { 15 | return "ExprNode(name: \"\(name)\")" 16 | } 17 | public init(name: String) { 18 | self.name = name 19 | } 20 | } 21 | 22 | public func == (lhs: ExprNode, rhs: ExprNode) -> Bool { 23 | return lhs.description == rhs.description 24 | } 25 | 26 | public class NumberNode: ExprNode { 27 | public let value: Float 28 | public override var description: String { 29 | return "NumberNode(value: \(value))" 30 | } 31 | public init(value: Float) { 32 | self.value = value 33 | super.init(name: "\(value)") 34 | } 35 | } 36 | 37 | public class VariableNode: ExprNode { 38 | public override var description: String { 39 | return "VariableNode(name: \"\(name)\")" 40 | } 41 | } 42 | 43 | public class BinaryOpNode: ExprNode { 44 | public let lhs: ExprNode 45 | public let rhs: ExprNode 46 | public override var description: String { 47 | return "BinaryOpNode(name: \"\(name)\", lhs: \(lhs), rhs: \(rhs))" 48 | } 49 | public init(name: String, lhs: ExprNode, rhs: ExprNode) { 50 | self.lhs = lhs 51 | self.rhs = rhs 52 | super.init(name: "\(name)") 53 | } 54 | } 55 | 56 | public class CallNode: ExprNode { 57 | public let arguments: [ExprNode] 58 | public override var description: String { 59 | return "CallNode(name: \"\(name)\", arguments: \(arguments))" 60 | } 61 | public init(name: String, arguments: [ExprNode]) { 62 | self.arguments = arguments 63 | super.init(name: "\(name)") 64 | } 65 | } 66 | 67 | public class PrototypeNode: ExprNode { 68 | public let argumentNames: [String] 69 | public override var description: String { 70 | return "PrototypeNode(name: \"\(name)\", argumentNames: \(argumentNames))" 71 | } 72 | public init(name: String, argumentNames: [String]) { 73 | self.argumentNames = argumentNames 74 | super.init(name: "\(name)") 75 | } 76 | } 77 | 78 | public class FunctionNode: ExprNode { 79 | public let prototype: PrototypeNode 80 | public let body: ExprNode 81 | public override var description: String { 82 | return "FunctionNode(prototype: \(prototype), body: \(body))" 83 | } 84 | public init(prototype: PrototypeNode, body: ExprNode) { 85 | self.prototype = prototype 86 | self.body = body 87 | super.init(name: "\(prototype.name)") 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /Pods/Hero/Sources/Parser/Parser.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Parser.swift 3 | // Kaleidoscope 4 | // 5 | // Created by Matthew Cheok on 15/11/15. 6 | // Copyright © 2015 Matthew Cheok. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | public enum ParseError: Error { 12 | case unexpectToken 13 | case undefinedOperator(String) 14 | 15 | case expectCharacter(Character) 16 | case expectExpression 17 | case expectArgumentList 18 | case expectFunctionName 19 | } 20 | 21 | public class Parser { 22 | let tokens: [Token] 23 | var index = 0 24 | 25 | public init(tokens: [Token]) { 26 | self.tokens = tokens 27 | } 28 | 29 | func peekCurrentToken() -> Token { 30 | if index >= tokens.count { 31 | return .other("", 0..<0) 32 | } 33 | return tokens[index] 34 | } 35 | 36 | @discardableResult func popCurrentToken() -> Token { 37 | defer { index += 1 } 38 | return tokens[index] 39 | } 40 | 41 | func parseNumber() throws -> ExprNode { 42 | guard case let .number(value, _) = popCurrentToken() else { 43 | throw ParseError.unexpectToken 44 | } 45 | return NumberNode(value: value) 46 | } 47 | 48 | func parseExpression() throws -> ExprNode { 49 | let node = try parsePrimary() 50 | return try parseBinaryOp(node: node) 51 | } 52 | 53 | func parseParens() throws -> ExprNode { 54 | guard case .parensOpen = popCurrentToken() else { 55 | throw ParseError.expectCharacter("(") 56 | } 57 | 58 | let exp = try parseExpression() 59 | 60 | guard case .parensClose = popCurrentToken() else { 61 | throw ParseError.expectCharacter(")") 62 | } 63 | 64 | return exp 65 | } 66 | 67 | func parseIdentifier() throws -> ExprNode { 68 | guard case let .identifier(name, _) = popCurrentToken() else { 69 | throw ParseError.unexpectToken 70 | } 71 | 72 | guard case .parensOpen = peekCurrentToken() else { 73 | return VariableNode(name: name) 74 | } 75 | popCurrentToken() 76 | 77 | var arguments = [ExprNode]() 78 | if case .parensClose = peekCurrentToken() { 79 | } else { 80 | while true { 81 | let argument = try parseExpression() 82 | arguments.append(argument) 83 | 84 | if case .parensClose = peekCurrentToken() { 85 | break 86 | } 87 | 88 | guard case .comma = popCurrentToken() else { 89 | throw ParseError.expectArgumentList 90 | } 91 | } 92 | } 93 | 94 | popCurrentToken() 95 | return CallNode(name: name, arguments: arguments) 96 | } 97 | 98 | func parsePrimary() throws -> ExprNode { 99 | switch peekCurrentToken() { 100 | case .identifier: 101 | return try parseIdentifier() 102 | case .number: 103 | return try parseNumber() 104 | case .parensOpen: 105 | return try parseParens() 106 | default: 107 | throw ParseError.expectExpression 108 | } 109 | } 110 | 111 | let operatorPrecedence: [String: Int] = [ 112 | "+": 20, 113 | "-": 20, 114 | "*": 40, 115 | "/": 40 116 | ] 117 | 118 | func getCurrentTokenPrecedence() throws -> Int { 119 | guard index < tokens.count else { 120 | return -1 121 | } 122 | 123 | guard case let .other(op, _) = peekCurrentToken() else { 124 | return -1 125 | } 126 | 127 | guard let precedence = operatorPrecedence[op] else { 128 | throw ParseError.undefinedOperator(op) 129 | } 130 | 131 | return precedence 132 | } 133 | 134 | func parseBinaryOp(node: ExprNode, exprPrecedence: Int = 0) throws -> ExprNode { 135 | var lhs = node 136 | while true { 137 | let tokenPrecedence = try getCurrentTokenPrecedence() 138 | if tokenPrecedence < exprPrecedence { 139 | return lhs 140 | } 141 | 142 | guard case let .other(op, _) = popCurrentToken() else { 143 | throw ParseError.unexpectToken 144 | } 145 | 146 | var rhs = try parsePrimary() 147 | let nextPrecedence = try getCurrentTokenPrecedence() 148 | 149 | if tokenPrecedence < nextPrecedence { 150 | rhs = try parseBinaryOp(node: rhs, exprPrecedence: tokenPrecedence+1) 151 | } 152 | lhs = BinaryOpNode(name: op, lhs: lhs, rhs: rhs) 153 | } 154 | } 155 | 156 | public func parse() throws -> [ExprNode] { 157 | index = 0 158 | 159 | var nodes = [ExprNode]() 160 | while index < tokens.count { 161 | let expr = try parsePrimary() 162 | nodes.append(expr) 163 | } 164 | 165 | return nodes 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /Pods/Hero/Sources/Parser/Regex.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Regex.swift 3 | // Kaleidoscope 4 | // 5 | // Created by Matthew Cheok on 15/11/15. 6 | // Copyright © 2015 Matthew Cheok. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | var expressions = [String: NSRegularExpression]() 12 | public extension String { 13 | public func match(regex: String) -> (String, CountableRange)? { 14 | let expression: NSRegularExpression 15 | if let exists = expressions[regex] { 16 | expression = exists 17 | } else { 18 | do { 19 | expression = try NSRegularExpression(pattern: "^\(regex)", options: []) 20 | expressions[regex] = expression 21 | } catch { 22 | return nil 23 | } 24 | } 25 | 26 | let range = expression.rangeOfFirstMatch(in: self, options: [], range: NSRange(0 ..< self.utf16.count)) 27 | if range.location != NSNotFound { 28 | return ((self as NSString).substring(with: range), range.location ..< range.location + range.length ) 29 | } 30 | return nil 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Pods/Hero/Sources/Preprocessors/BasePreprocessor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CascadeEffect.swift 3 | // The MIT License (MIT) 4 | // 5 | // Copyright (c) 2016 Luke Zhao 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | 25 | import UIKit 26 | 27 | class BasePreprocessor: HeroPreprocessor { 28 | weak public var hero: HeroTransition! 29 | public var context: HeroContext! { 30 | return hero?.context 31 | } 32 | 33 | func process(fromViews: [UIView], toViews: [UIView]) {} 34 | } 35 | -------------------------------------------------------------------------------- /Pods/Hero/Sources/Preprocessors/CascadePreprocessor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CascadeEffect.swift 3 | // The MIT License (MIT) 4 | // 5 | // Copyright (c) 2016 Luke Zhao 6 | // 7 | // Permission is hereby granted, free of charge, to any person obtaining a copy 8 | // of this software and associated documentation files (the "Software"), to deal 9 | // in the Software without restriction, including without limitation the rights 10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | // copies of the Software, and to permit persons to whom the Software is 12 | // furnished to do so, subject to the following conditions: 13 | // 14 | // The above copyright notice and this permission notice shall be included in 15 | // all copies or substantial portions of the Software. 16 | // 17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | // THE SOFTWARE. 24 | 25 | import UIKit 26 | 27 | public enum CascadeDirection { 28 | case topToBottom 29 | case bottomToTop 30 | case leftToRight 31 | case rightToLeft 32 | case radial(center:CGPoint) 33 | case inverseRadial(center:CGPoint) 34 | var comparator: (UIView, UIView) -> Bool { 35 | switch self { 36 | case .topToBottom: 37 | return { return $0.frame.minY < $1.frame.minY } 38 | case .bottomToTop: 39 | return { return $0.frame.maxY == $1.frame.maxY ? $0.frame.maxX > $1.frame.maxX : $0.frame.maxY > $1.frame.maxY } 40 | case .leftToRight: 41 | return { return $0.frame.minX < $1.frame.minX } 42 | case .rightToLeft: 43 | return { return $0.frame.maxX > $1.frame.maxX } 44 | case .radial(let center): 45 | return { return $0.center.distance(center) < $1.center.distance(center) } 46 | case .inverseRadial(let center): 47 | return { return $0.center.distance(center) > $1.center.distance(center) } 48 | } 49 | } 50 | 51 | init?(_ string: String) { 52 | switch string { 53 | case "bottomToTop": 54 | self = .bottomToTop 55 | case "leftToRight": 56 | self = .leftToRight 57 | case "rightToLeft": 58 | self = .rightToLeft 59 | case "topToBottom": 60 | self = .topToBottom 61 | default: 62 | return nil 63 | } 64 | } 65 | } 66 | 67 | class CascadePreprocessor: BasePreprocessor { 68 | override func process(fromViews: [UIView], toViews: [UIView]) { 69 | process(views:fromViews) 70 | process(views:toViews) 71 | } 72 | 73 | func process(views: [UIView]) { 74 | for view in views { 75 | guard let (deltaTime, direction, delayMatchedViews) = context[view]?.cascade else { continue } 76 | 77 | var parentView = view 78 | if view is UITableView, let wrapperView = view.subviews.get(0) { 79 | parentView = wrapperView 80 | } 81 | 82 | let sortedSubviews = parentView.subviews.sorted(by: direction.comparator) 83 | 84 | let initialDelay = context[view]!.delay 85 | let finalDelay = TimeInterval(sortedSubviews.count) * deltaTime + initialDelay 86 | 87 | for (i, subview) in sortedSubviews.enumerated() { 88 | let delay = TimeInterval(i) * deltaTime + initialDelay 89 | 90 | func applyDelay(view: UIView) { 91 | if context.pairedView(for: view) == nil { 92 | context[view]?.delay = delay 93 | } else if delayMatchedViews, let paired = context.pairedView(for: view) { 94 | context[view]?.delay = finalDelay 95 | context[paired]?.delay = finalDelay 96 | } 97 | for subview in view.subviews { 98 | applyDelay(view: subview) 99 | } 100 | } 101 | 102 | applyDelay(view: subview) 103 | } 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /Pods/Hero/Sources/Preprocessors/ConditionalPreprocessor.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2016 Luke Zhao 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | public struct HeroConditionalContext { 26 | internal weak var hero: HeroTransition! 27 | public weak var view: UIView! 28 | 29 | public private(set) var isAppearing: Bool 30 | 31 | public var isPresenting: Bool { 32 | return hero.isPresenting 33 | } 34 | public var isInTabbarController: Bool { 35 | return hero.inTabBarController 36 | } 37 | public var isInNavbarController: Bool { 38 | return hero.inNavigationController 39 | } 40 | public var isMatched: Bool { 41 | return matchedView != nil 42 | } 43 | public var isAncestorViewMatched: Bool { 44 | return matchedAncestorView != nil 45 | } 46 | 47 | public var matchedView: UIView? { 48 | return hero.context.pairedView(for: view) 49 | } 50 | public var matchedAncestorView: (UIView, UIView)? { 51 | var current = view.superview 52 | while let ancestor = current, ancestor != hero.context.container { 53 | if let pairedView = hero.context.pairedView(for: ancestor) { 54 | return (ancestor, pairedView) 55 | } 56 | current = ancestor.superview 57 | } 58 | return nil 59 | } 60 | 61 | public var fromViewController: UIViewController { 62 | return hero.fromViewController! 63 | } 64 | public var toViewController: UIViewController { 65 | return hero.toViewController! 66 | } 67 | public var currentViewController: UIViewController { 68 | return isAppearing ? toViewController : fromViewController 69 | } 70 | public var otherViewController: UIViewController { 71 | return isAppearing ? fromViewController : toViewController 72 | } 73 | } 74 | 75 | class ConditionalPreprocessor: BasePreprocessor { 76 | override func process(fromViews: [UIView], toViews: [UIView]) { 77 | process(views:fromViews, appearing: false) 78 | process(views:toViews, appearing: true) 79 | } 80 | 81 | func process(views: [UIView], appearing: Bool) { 82 | for view in views { 83 | guard let conditionalModifiers = context[view]?.conditionalModifiers else { continue } 84 | for (condition, modifiers) in conditionalModifiers { 85 | if condition(HeroConditionalContext(hero: hero, view: view, isAppearing: appearing)) { 86 | context[view]!.append(contentsOf: modifiers) 87 | } 88 | } 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /Pods/Hero/Sources/Preprocessors/IgnoreSubviewModifiersPreprocessor.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2016 Luke Zhao 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | class IgnoreSubviewModifiersPreprocessor: BasePreprocessor { 26 | override func process(fromViews: [UIView], toViews: [UIView]) { 27 | process(views:fromViews) 28 | process(views:toViews) 29 | } 30 | 31 | func process(views: [UIView]) { 32 | for view in views { 33 | guard let recursive = context[view]?.ignoreSubviewModifiers else { continue } 34 | var parentView = view 35 | if view is UITableView, let wrapperView = view.subviews.get(0) { 36 | parentView = wrapperView 37 | } 38 | 39 | if recursive { 40 | cleanSubviewModifiers(parentView) 41 | } else { 42 | for subview in parentView.subviews { 43 | context[subview] = nil 44 | } 45 | } 46 | } 47 | } 48 | 49 | private func cleanSubviewModifiers(_ parentView: UIView) { 50 | for view in parentView.subviews { 51 | context[view] = nil 52 | cleanSubviewModifiers(view) 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Pods/Hero/Sources/Preprocessors/MatchPreprocessor.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2016 Luke Zhao 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | class MatchPreprocessor: BasePreprocessor { 26 | override func process(fromViews: [UIView], toViews: [UIView]) { 27 | for tv in toViews { 28 | guard let id = tv.heroID, let fv = context.sourceView(for: id) else { continue } 29 | 30 | var tvState = context[tv] ?? HeroTargetState() 31 | var fvState = context[fv] ?? HeroTargetState() 32 | 33 | // match is just a two-way source effect 34 | tvState.source = id 35 | fvState.source = id 36 | 37 | fvState.arc = tvState.arc 38 | fvState.duration = tvState.duration 39 | fvState.timingFunction = tvState.timingFunction 40 | fvState.delay = tvState.delay 41 | fvState.spring = tvState.spring 42 | 43 | let forceNonFade = tvState.nonFade || fvState.nonFade 44 | let isNonOpaque = !fv.isOpaque || fv.alpha < 1 || !tv.isOpaque || tv.alpha < 1 45 | 46 | if context.insertToViewFirst { 47 | fvState.opacity = 0 48 | if !forceNonFade && isNonOpaque { 49 | tvState.opacity = 0 50 | } else { 51 | tvState.opacity = nil 52 | if !tv.layer.masksToBounds && tvState.displayShadow { 53 | fvState.displayShadow = false 54 | } 55 | } 56 | } else { 57 | tvState.opacity = 0 58 | if !forceNonFade && isNonOpaque { 59 | // cross fade if from/toViews are not opaque 60 | fvState.opacity = 0 61 | } else { 62 | // no cross fade in this case, fromView is always displayed during the transition. 63 | fvState.opacity = nil 64 | 65 | // we dont want two shadows showing up. Therefore we disable toView's shadow when fromView is able to display its shadow 66 | if !fv.layer.masksToBounds && fvState.displayShadow { 67 | tvState.displayShadow = false 68 | } 69 | } 70 | } 71 | 72 | context[tv] = tvState 73 | context[fv] = fvState 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /Pods/Hero/Sources/Preprocessors/SourcePreprocessor.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2016 Luke Zhao 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | class SourcePreprocessor: BasePreprocessor { 26 | override func process(fromViews: [UIView], toViews: [UIView]) { 27 | for fv in fromViews { 28 | guard let id = context[fv]?.source, 29 | let tv = context.destinationView(for: id) else { continue } 30 | prepareFor(view: fv, targetView: tv) 31 | } 32 | for tv in toViews { 33 | guard let id = context[tv]?.source, 34 | let fv = context.sourceView(for: id) else { continue } 35 | prepareFor(view: tv, targetView: fv) 36 | } 37 | } 38 | 39 | func prepareFor(view: UIView, targetView: UIView) { 40 | let targetPos = context.container.convert(targetView.layer.position, from: targetView.superview!) 41 | let targetTransform = context.container.layer.flatTransformTo(layer: targetView.layer) 42 | 43 | var state = context[view]! 44 | 45 | // use global coordinate space since over target position is converted from the global container 46 | state.coordinateSpace = .global 47 | 48 | state.position = targetPos 49 | state.transform = targetTransform 50 | 51 | // remove incompatible options 52 | state.size = nil 53 | state.cornerRadius = nil 54 | 55 | if view.bounds.size != targetView.bounds.size { 56 | state.size = targetView.bounds.size 57 | } 58 | if view.layer.cornerRadius != targetView.layer.cornerRadius { 59 | state.cornerRadius = targetView.layer.cornerRadius 60 | } 61 | if view.layer.shadowColor != targetView.layer.shadowColor { 62 | state.shadowColor = targetView.layer.shadowColor 63 | } 64 | if view.layer.shadowOpacity != targetView.layer.shadowOpacity { 65 | state.shadowOpacity = targetView.layer.shadowOpacity 66 | } 67 | if view.layer.shadowOffset != targetView.layer.shadowOffset { 68 | state.shadowOffset = targetView.layer.shadowOffset 69 | } 70 | if view.layer.shadowRadius != targetView.layer.shadowRadius { 71 | state.shadowRadius = targetView.layer.shadowRadius 72 | } 73 | if view.layer.shadowPath != targetView.layer.shadowPath { 74 | state.shadowPath = targetView.layer.shadowPath 75 | } 76 | if view.layer.contentsRect != targetView.layer.contentsRect { 77 | state.contentsRect = targetView.layer.contentsRect 78 | } 79 | if view.layer.contentsScale != targetView.layer.contentsScale { 80 | state.contentsScale = targetView.layer.contentsScale 81 | } 82 | 83 | context[view] = state 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /Pods/Hero/Sources/Transition/HeroProgressRunner.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2016 Luke Zhao 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | protocol HeroProgressRunnerDelegate: class { 26 | func updateProgress(progress: Double) 27 | func complete(finished: Bool) 28 | } 29 | 30 | class HeroProgressRunner { 31 | weak var delegate: HeroProgressRunnerDelegate? 32 | 33 | var isRunning: Bool { 34 | return displayLink != nil 35 | } 36 | internal var timePassed: TimeInterval = 0.0 37 | internal var duration: TimeInterval = 0.0 38 | internal var displayLink: CADisplayLink? 39 | internal var isReversed: Bool = false 40 | 41 | @objc func displayUpdate(_ link: CADisplayLink) { 42 | timePassed += isReversed ? -link.duration : link.duration 43 | if isReversed, timePassed <= 1.0 / 120 { 44 | delegate?.complete(finished: false) 45 | stop() 46 | return 47 | } 48 | 49 | if !isReversed, timePassed > duration - 1.0 / 120 { 50 | delegate?.complete(finished: true) 51 | stop() 52 | return 53 | } 54 | 55 | delegate?.updateProgress(progress: timePassed / duration) 56 | } 57 | 58 | func start(timePassed: TimeInterval, totalTime: TimeInterval, reverse: Bool) { 59 | stop() 60 | self.timePassed = timePassed 61 | self.isReversed = reverse 62 | self.duration = totalTime 63 | displayLink = CADisplayLink(target: self, selector: #selector(displayUpdate(_:))) 64 | displayLink!.add(to: RunLoop.main, forMode: RunLoopMode(rawValue: RunLoopMode.commonModes.rawValue)) 65 | } 66 | 67 | func stop() { 68 | displayLink?.isPaused = true 69 | displayLink?.remove(from: RunLoop.main, forMode: RunLoopMode(rawValue: RunLoopMode.commonModes.rawValue)) 70 | displayLink = nil 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /Pods/Hero/Sources/Transition/HeroTransition+Animate.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2016 Luke Zhao 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import Foundation 24 | 25 | extension HeroTransition { 26 | open func animate() { 27 | guard state == .starting else { return } 28 | state = .animating 29 | 30 | if let toView = toView { 31 | context.unhide(view: toView) 32 | } 33 | 34 | // auto hide all animated views 35 | for view in animatingFromViews { 36 | context.hide(view: view) 37 | } 38 | for view in animatingToViews { 39 | context.hide(view: view) 40 | } 41 | 42 | var totalDuration: TimeInterval = 0 43 | var animatorWantsInteractive = false 44 | 45 | if context.insertToViewFirst { 46 | for v in animatingToViews { _ = context.snapshotView(for: v) } 47 | for v in animatingFromViews { _ = context.snapshotView(for: v) } 48 | } else { 49 | for v in animatingFromViews { _ = context.snapshotView(for: v) } 50 | for v in animatingToViews { _ = context.snapshotView(for: v) } 51 | } 52 | 53 | // UIKit appears to set fromView setNeedLayout to be true. 54 | // We don't want fromView to layout after our animation starts. 55 | // Therefore we kick off the layout beforehand 56 | fromView?.layoutIfNeeded() 57 | 58 | for animator in animators { 59 | let duration = animator.animate(fromViews: animatingFromViews.filter({ animator.canAnimate(view: $0, appearing: false) }), 60 | toViews: animatingToViews.filter({ animator.canAnimate(view: $0, appearing: true) })) 61 | if duration == .infinity { 62 | animatorWantsInteractive = true 63 | } else { 64 | totalDuration = max(totalDuration, duration) 65 | } 66 | } 67 | 68 | self.totalDuration = totalDuration 69 | if let forceFinishing = forceFinishing { 70 | complete(finished: forceFinishing) 71 | } else if animatorWantsInteractive { 72 | update(0) 73 | } else { 74 | complete(after: totalDuration, finishing: true) 75 | } 76 | 77 | fullScreenSnapshot?.removeFromSuperview() 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /Pods/Hero/Sources/Transition/HeroTransition+Complete.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2016 Luke Zhao 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | extension HeroTransition { 26 | open func complete(finished: Bool) { 27 | if state == .notified { 28 | forceFinishing = finished 29 | } 30 | guard state == .animating || state == .starting else { return } 31 | defer { 32 | transitionContext = nil 33 | fromViewController = nil 34 | toViewController = nil 35 | inNavigationController = false 36 | inTabBarController = false 37 | forceNotInteractive = false 38 | animatingToViews.removeAll() 39 | animatingFromViews.removeAll() 40 | progressUpdateObservers = nil 41 | transitionContainer = nil 42 | completionCallback = nil 43 | forceFinishing = nil 44 | container = nil 45 | processors.removeAll() 46 | animators.removeAll() 47 | plugins.removeAll() 48 | context = nil 49 | progress = 0 50 | totalDuration = 0 51 | state = .possible 52 | } 53 | state = .completing 54 | 55 | progressRunner.stop() 56 | context.clean() 57 | 58 | if let toView = toView, let fromView = fromView { 59 | if finished && isPresenting && toOverFullScreen { 60 | // finished presenting a overFullScreen VC 61 | context.unhide(rootView: toView) 62 | context.removeSnapshots(rootView: toView) 63 | context.storeViewAlpha(rootView: fromView) 64 | fromViewController?.heroStoredSnapshot = container 65 | container.superview?.addSubview(fromView) 66 | fromView.addSubview(container) 67 | } else if !finished && !isPresenting && fromOverFullScreen { 68 | // cancelled dismissing a overFullScreen VC 69 | context.unhide(rootView: fromView) 70 | context.removeSnapshots(rootView: fromView) 71 | context.storeViewAlpha(rootView: toView) 72 | toViewController?.heroStoredSnapshot = container 73 | container.superview?.addSubview(toView) 74 | toView.addSubview(container) 75 | } else { 76 | context.unhideAll() 77 | context.removeAllSnapshots() 78 | } 79 | 80 | // move fromView & toView back from our container back to the one supplied by UIKit 81 | if (toOverFullScreen && finished) || (fromOverFullScreen && !finished) { 82 | transitionContainer?.addSubview(finished ? fromView : toView) 83 | } 84 | transitionContainer?.addSubview(finished ? toView : fromView) 85 | 86 | if isPresenting != finished, !inContainerController, transitionContext != nil { 87 | // only happens when present a .overFullScreen VC 88 | // bug: http://openradar.appspot.com/radar?id=5320103646199808 89 | UIApplication.shared.keyWindow?.addSubview(isPresenting ? fromView : toView) 90 | } 91 | } 92 | 93 | if container.superview == transitionContainer { 94 | container.removeFromSuperview() 95 | } 96 | 97 | for animator in animators { 98 | animator.clean() 99 | } 100 | 101 | transitionContainer?.isUserInteractionEnabled = true 102 | 103 | completionCallback?(finished) 104 | 105 | if finished { 106 | if let fvc = fromViewController, let tvc = toViewController { 107 | closureProcessForHeroDelegate(vc: fvc) { 108 | $0.heroDidEndAnimatingTo?(viewController: tvc) 109 | $0.heroDidEndTransition?() 110 | } 111 | 112 | closureProcessForHeroDelegate(vc: tvc) { 113 | $0.heroDidEndAnimatingFrom?(viewController: fvc) 114 | $0.heroDidEndTransition?() 115 | } 116 | } 117 | transitionContext?.finishInteractiveTransition() 118 | } else { 119 | if let fvc = fromViewController, let tvc = toViewController { 120 | closureProcessForHeroDelegate(vc: fvc) { 121 | $0.heroDidCancelAnimatingTo?(viewController: tvc) 122 | $0.heroDidCancelTransition?() 123 | } 124 | 125 | closureProcessForHeroDelegate(vc: tvc) { 126 | $0.heroDidCancelAnimatingFrom?(viewController: fvc) 127 | $0.heroDidCancelTransition?() 128 | } 129 | } 130 | transitionContext?.cancelInteractiveTransition() 131 | } 132 | transitionContext?.completeTransition(finished) 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /Pods/Hero/Sources/Transition/HeroTransition+CustomTransition.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2016 Luke Zhao 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | // custom transition helper, used in hero_replaceViewController 26 | public extension HeroTransition { 27 | public func transition(from: UIViewController, to: UIViewController, in view: UIView, completion: ((Bool) -> Void)? = nil) { 28 | guard !isTransitioning else { return } 29 | self.state = .notified 30 | isPresenting = true 31 | transitionContainer = view 32 | fromViewController = from 33 | toViewController = to 34 | completionCallback = { 35 | completion?($0) 36 | self.state = .possible 37 | } 38 | start() 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Pods/Hero/Sources/Transition/HeroTransition+Interactive.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2016 Luke Zhao 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | extension HeroTransition { 26 | /** 27 | Update the progress for the interactive transition. 28 | - Parameters: 29 | - progress: the current progress, must be between -1...1 30 | */ 31 | public func update(_ percentageComplete: CGFloat) { 32 | guard state == .animating else { return } 33 | self.progressRunner.stop() 34 | self.progress = max(-1, min(1, Double(percentageComplete))) 35 | } 36 | 37 | /** 38 | Finish the interactive transition. 39 | Will stop the interactive transition and animate from the 40 | current state to the **end** state 41 | */ 42 | public func finish(animate: Bool = true) { 43 | guard state == .animating || state == .notified || state == .starting else { return } 44 | if !animate { 45 | self.complete(finished:true) 46 | return 47 | } 48 | var maxTime: TimeInterval = 0 49 | for animator in self.animators { 50 | maxTime = max(maxTime, animator.resume(timePassed:self.progress * self.totalDuration, 51 | reverse: false)) 52 | } 53 | self.complete(after: maxTime, finishing: true) 54 | } 55 | 56 | /** 57 | Cancel the interactive transition. 58 | Will stop the interactive transition and animate from the 59 | current state to the **beginning** state 60 | */ 61 | public func cancel(animate: Bool = true) { 62 | guard state == .animating || state == .notified || state == .starting else { return } 63 | if !animate { 64 | self.complete(finished:false) 65 | return 66 | } 67 | var maxTime: TimeInterval = 0 68 | for animator in self.animators { 69 | var adjustedProgress = self.progress 70 | if adjustedProgress < 0 { 71 | adjustedProgress = -adjustedProgress 72 | } 73 | maxTime = max(maxTime, animator.resume(timePassed:adjustedProgress * self.totalDuration, 74 | reverse: true)) 75 | } 76 | self.complete(after: maxTime, finishing: false) 77 | } 78 | 79 | /** 80 | Override modifiers during an interactive animation. 81 | 82 | For example: 83 | 84 | Hero.shared.apply([.position(x:50, y:50)], to:view) 85 | 86 | will set the view's position to 50, 50 87 | - Parameters: 88 | - modifiers: the modifiers to override 89 | - view: the view to override to 90 | */ 91 | public func apply(modifiers: [HeroModifier], to view: UIView) { 92 | guard state == .animating else { return } 93 | let targetState = HeroTargetState(modifiers: modifiers) 94 | if let otherView = self.context.pairedView(for: view) { 95 | for animator in self.animators { 96 | animator.apply(state: targetState, to: otherView) 97 | } 98 | } 99 | for animator in self.animators { 100 | animator.apply(state: targetState, to: view) 101 | } 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /Pods/Hero/Sources/Transition/HeroTransition+Start.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2016 Luke Zhao 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | extension HeroTransition { 26 | open func start() { 27 | guard state == .notified else { return } 28 | state = .starting 29 | 30 | if let toView = toView, let fromView = fromView { 31 | toView.frame = fromView.frame 32 | toView.setNeedsLayout() 33 | toView.layoutIfNeeded() 34 | } 35 | 36 | if let fvc = fromViewController, let tvc = toViewController { 37 | closureProcessForHeroDelegate(vc: fvc) { 38 | $0.heroWillStartTransition?() 39 | $0.heroWillStartAnimatingTo?(viewController: tvc) 40 | } 41 | 42 | closureProcessForHeroDelegate(vc: tvc) { 43 | $0.heroWillStartTransition?() 44 | $0.heroWillStartAnimatingFrom?(viewController: fvc) 45 | } 46 | } 47 | 48 | // take a snapshot to hide all the flashing that might happen 49 | fullScreenSnapshot = transitionContainer?.window?.snapshotView(afterScreenUpdates: false) ?? fromView?.snapshotView(afterScreenUpdates: false) 50 | if let fullScreenSnapshot = fullScreenSnapshot { 51 | (transitionContainer?.window ?? transitionContainer)?.addSubview(fullScreenSnapshot) 52 | } 53 | 54 | if let oldSnapshot = fromViewController?.heroStoredSnapshot { 55 | oldSnapshot.removeFromSuperview() 56 | fromViewController?.heroStoredSnapshot = nil 57 | } 58 | if let oldSnapshot = toViewController?.heroStoredSnapshot { 59 | oldSnapshot.removeFromSuperview() 60 | toViewController?.heroStoredSnapshot = nil 61 | } 62 | 63 | plugins = HeroTransition.enabledPlugins.map({ return $0.init() }) 64 | processors = [ 65 | IgnoreSubviewModifiersPreprocessor(), 66 | ConditionalPreprocessor(), 67 | DefaultAnimationPreprocessor(), 68 | MatchPreprocessor(), 69 | SourcePreprocessor(), 70 | CascadePreprocessor() 71 | ] 72 | animators = [ 73 | HeroDefaultAnimator() 74 | ] 75 | 76 | if #available(iOS 10, tvOS 10, *) { 77 | animators.append(HeroDefaultAnimator()) 78 | } 79 | 80 | // There is no covariant in Swift, so we need to add plugins one by one. 81 | for plugin in plugins { 82 | processors.append(plugin) 83 | animators.append(plugin) 84 | } 85 | 86 | transitionContainer?.isUserInteractionEnabled = isUserInteractionEnabled 87 | 88 | // a view to hold all the animating views 89 | container = UIView(frame: transitionContainer?.bounds ?? .zero) 90 | if !toOverFullScreen && !fromOverFullScreen { 91 | container.backgroundColor = containerColor 92 | } 93 | transitionContainer?.addSubview(container) 94 | 95 | context = HeroContext(container:container) 96 | 97 | for processor in processors { 98 | processor.hero = self 99 | } 100 | for animator in animators { 101 | animator.hero = self 102 | } 103 | 104 | if let toView = toView, let fromView = fromView { 105 | context.loadViewAlpha(rootView: toView) 106 | context.loadViewAlpha(rootView: fromView) 107 | container.addSubview(toView) 108 | container.addSubview(fromView) 109 | 110 | toView.updateConstraints() 111 | toView.setNeedsLayout() 112 | toView.layoutIfNeeded() 113 | 114 | context.set(fromViews: fromView.flattenedViewHierarchy, toViews: toView.flattenedViewHierarchy) 115 | } 116 | 117 | if (viewOrderingStrategy == .auto && !isPresenting && !inTabBarController) || 118 | viewOrderingStrategy == .sourceViewOnTop { 119 | context.insertToViewFirst = true 120 | } 121 | 122 | for processor in processors { 123 | processor.process(fromViews: context.fromViews, toViews: context.toViews) 124 | } 125 | animatingFromViews = context.fromViews.filter { (view: UIView) -> Bool in 126 | for animator in animators { 127 | if animator.canAnimate(view: view, appearing: false) { 128 | return true 129 | } 130 | } 131 | return false 132 | } 133 | animatingToViews = context.toViews.filter { (view: UIView) -> Bool in 134 | for animator in animators { 135 | if animator.canAnimate(view: view, appearing: true) { 136 | return true 137 | } 138 | } 139 | return false 140 | } 141 | 142 | if let toView = toView { 143 | context.hide(view: toView) 144 | } 145 | 146 | #if os(tvOS) 147 | animate() 148 | #else 149 | if inNavigationController { 150 | // When animating within navigationController, we have to dispatch later into the main queue. 151 | // otherwise snapshots will be pure white. Possibly a bug with UIKit 152 | DispatchQueue.main.async { 153 | self.animate() 154 | } 155 | } else { 156 | animate() 157 | } 158 | #endif 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /Pods/Hero/Sources/Transition/HeroTransition+UINavigationControllerDelegate.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2016 Luke Zhao 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | extension HeroTransition: UINavigationControllerDelegate { 26 | public func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationControllerOperation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? { 27 | guard !isTransitioning else { return nil } 28 | self.state = .notified 29 | self.isPresenting = operation == .push 30 | self.fromViewController = fromViewController ?? fromVC 31 | self.toViewController = toViewController ?? toVC 32 | self.inNavigationController = true 33 | return self 34 | } 35 | 36 | public func navigationController(_ navigationController: UINavigationController, interactionControllerFor animationController: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? { 37 | return interactiveTransitioning 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Pods/Hero/Sources/Transition/HeroTransition+UITabBarControllerDelegate.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2016 Luke Zhao 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | extension HeroTransition: UITabBarControllerDelegate { 26 | public func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool { 27 | if isTransitioning { 28 | cancel(animate: false) 29 | } 30 | return true 31 | } 32 | 33 | public func tabBarController(_ tabBarController: UITabBarController, interactionControllerFor animationController: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? { 34 | return interactiveTransitioning 35 | } 36 | 37 | public func tabBarController(_ tabBarController: UITabBarController, animationControllerForTransitionFrom fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? { 38 | guard !isTransitioning else { return nil } 39 | self.state = .notified 40 | let fromVCIndex = tabBarController.childViewControllers.index(of: fromVC)! 41 | let toVCIndex = tabBarController.childViewControllers.index(of: toVC)! 42 | self.isPresenting = toVCIndex > fromVCIndex 43 | self.fromViewController = fromViewController ?? fromVC 44 | self.toViewController = toViewController ?? toVC 45 | self.inTabBarController = true 46 | return self 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Pods/Hero/Sources/Transition/HeroTransition+UIViewControllerTransitioningDelegate.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2016 Luke Zhao 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import UIKit 24 | 25 | extension HeroTransition:UIViewControllerTransitioningDelegate { 26 | var interactiveTransitioning: UIViewControllerInteractiveTransitioning? { 27 | return forceNotInteractive ? nil : self 28 | } 29 | 30 | public func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? { 31 | guard !isTransitioning else { return nil } 32 | self.state = .notified 33 | self.isPresenting = true 34 | self.fromViewController = fromViewController ?? presenting 35 | self.toViewController = toViewController ?? presented 36 | return self 37 | } 38 | 39 | public func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { 40 | guard !isTransitioning else { return nil } 41 | self.state = .notified 42 | self.isPresenting = false 43 | self.fromViewController = fromViewController ?? dismissed 44 | return self 45 | } 46 | 47 | public func interactionControllerForDismissal(using animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? { 48 | return interactiveTransitioning 49 | } 50 | 51 | public func interactionControllerForPresentation(using animator: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? { 52 | return interactiveTransitioning 53 | } 54 | } 55 | 56 | extension HeroTransition: UIViewControllerAnimatedTransitioning { 57 | public func animateTransition(using context: UIViewControllerContextTransitioning) { 58 | transitionContext = context 59 | fromViewController = fromViewController ?? context.viewController(forKey: .from) 60 | toViewController = toViewController ?? context.viewController(forKey: .to) 61 | transitionContainer = context.containerView 62 | start() 63 | } 64 | public func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { 65 | return 0.375 // doesn't matter, real duration will be calculated later 66 | } 67 | 68 | public func animationEnded(_ transitionCompleted: Bool) { 69 | self.state = .possible 70 | } 71 | } 72 | 73 | extension HeroTransition: UIViewControllerInteractiveTransitioning { 74 | public var wantsInteractiveStart: Bool { 75 | return true 76 | } 77 | public func startInteractiveTransition(_ transitionContext: UIViewControllerContextTransitioning) { 78 | animateTransition(using: transitionContext) 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /Pods/Hero/Sources/Transition/HeroTransitionState.swift: -------------------------------------------------------------------------------- 1 | // The MIT License (MIT) 2 | // 3 | // Copyright (c) 2016 Luke Zhao 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | import Foundation 24 | 25 | public enum HeroTransitionState: Int { 26 | // Hero is able to start a new transition 27 | case possible 28 | 29 | // UIKit has notified Hero about a pending transition. 30 | // Hero haven't started preparing. 31 | case notified 32 | 33 | // Hero's `start` method has been called. Preparing the animation. 34 | case starting 35 | 36 | // Hero's `animate` method has been called. Animation has started. 37 | case animating 38 | 39 | // Hero's `complete` method has been called. Transition is ended or cancelled. Hero is doing cleanup. 40 | case completing 41 | } 42 | -------------------------------------------------------------------------------- /Pods/Local Podspecs/Hero.podspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Hero", 3 | "version": "1.0.0", 4 | "summary": "Elegant transition library for iOS", 5 | "description": "Hero is a library for building iOS view controller transitions. It provides a declarative layer on top of the UIKit's cumbersome transition APIs. Making custom transitions an easy task for developers.", 6 | "homepage": "https://github.com/lkzhao/Hero", 7 | "screenshots": "https://github.com/lkzhao/Hero/blob/master/Resources/Hero.png?raw=true", 8 | "license": "MIT", 9 | "authors": { 10 | "Luke": "lzhaoyilun@gmail.com" 11 | }, 12 | "source": { 13 | "git": "https://github.com/lkzhao/Hero.git", 14 | "tag": "1.0.0" 15 | }, 16 | "platforms": { 17 | "ios": "8.0", 18 | "tvos": "9.0" 19 | }, 20 | "ios": { 21 | "frameworks": [ 22 | "UIKit", 23 | "Foundation" 24 | ] 25 | }, 26 | "requires_arc": true, 27 | "source_files": "Sources/**/*.swift" 28 | } 29 | -------------------------------------------------------------------------------- /Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Hero (1.0.0) 3 | 4 | DEPENDENCIES: 5 | - Hero (from `https://github.com/lkzhao/Hero.git`) 6 | 7 | EXTERNAL SOURCES: 8 | Hero: 9 | :git: https://github.com/lkzhao/Hero.git 10 | 11 | CHECKOUT OPTIONS: 12 | Hero: 13 | :commit: 5a9302c6ebdb1c36adb49d0803e61d5d0c9c5a91 14 | :git: https://github.com/lkzhao/Hero.git 15 | 16 | SPEC CHECKSUMS: 17 | Hero: a0481f995d78951544614a8e828f7eb374e73c06 18 | 19 | PODFILE CHECKSUM: 3cabcfd2218ed3e7f52e3046e9b9f10881ee4222 20 | 21 | COCOAPODS: 1.2.1 22 | -------------------------------------------------------------------------------- /Pods/Pods.xcodeproj/xcuserdata/mukesh.xcuserdatad/xcschemes/Hero.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 45 | 46 | 52 | 53 | 55 | 56 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /Pods/Pods.xcodeproj/xcuserdata/mukesh.xcuserdatad/xcschemes/Pods-MMPullSwipeDismiss.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 33 | 34 | 35 | 36 | 47 | 48 | 54 | 55 | 56 | 57 | 58 | 59 | 65 | 66 | 68 | 69 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /Pods/Pods.xcodeproj/xcuserdata/mukesh.xcuserdatad/xcschemes/Pods-MMPullSwipeDismissTests.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 33 | 34 | 35 | 36 | 47 | 48 | 54 | 55 | 56 | 57 | 58 | 59 | 65 | 66 | 68 | 69 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /Pods/Pods.xcodeproj/xcuserdata/mukesh.xcuserdatad/xcschemes/Pods-MMPullSwipeDismissUITests.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 33 | 34 | 35 | 36 | 47 | 48 | 54 | 55 | 56 | 57 | 58 | 59 | 65 | 66 | 68 | 69 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /Pods/Pods.xcodeproj/xcuserdata/mukesh.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Hero.xcscheme 8 | 9 | isShown 10 | 11 | orderHint 12 | 0 13 | 14 | Pods-MMPullSwipeDismiss.xcscheme 15 | 16 | isShown 17 | 18 | orderHint 19 | 1 20 | 21 | Pods-MMPullSwipeDismissTests.xcscheme 22 | 23 | isShown 24 | 25 | orderHint 26 | 2 27 | 28 | Pods-MMPullSwipeDismissUITests.xcscheme 29 | 30 | isShown 31 | 32 | orderHint 33 | 3 34 | 35 | 36 | SuppressBuildableAutocreation 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Hero/Hero-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Hero : NSObject 3 | @end 4 | @implementation PodsDummy_Hero 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Hero/Hero-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Hero/Hero-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double HeroVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char HeroVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Hero/Hero.modulemap: -------------------------------------------------------------------------------- 1 | framework module Hero { 2 | umbrella header "Hero-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Hero/Hero.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/Hero 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public" 4 | OTHER_LDFLAGS = -framework "Foundation" -framework "UIKit" 5 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 6 | PODS_BUILD_DIR = $BUILD_DIR 7 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_ROOT = ${SRCROOT} 9 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/Hero 10 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 11 | SKIP_INSTALL = YES 12 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Hero/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-MMPullSwipeDismiss/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-MMPullSwipeDismiss/Pods-MMPullSwipeDismiss-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## Hero 5 | 6 | The MIT License (MIT) 7 | 8 | Copyright (c) 2015 Luke Zhao 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in 18 | all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 | THE SOFTWARE. 27 | 28 | Generated by CocoaPods - https://cocoapods.org 29 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-MMPullSwipeDismiss/Pods-MMPullSwipeDismiss-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | The MIT License (MIT) 18 | 19 | Copyright (c) 2015 Luke Zhao <me@lkzhao.com> 20 | 21 | Permission is hereby granted, free of charge, to any person obtaining a copy 22 | of this software and associated documentation files (the "Software"), to deal 23 | in the Software without restriction, including without limitation the rights 24 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 25 | copies of the Software, and to permit persons to whom the Software is 26 | furnished to do so, subject to the following conditions: 27 | 28 | The above copyright notice and this permission notice shall be included in 29 | all copies or substantial portions of the Software. 30 | 31 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 32 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 33 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 34 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 35 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 36 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 37 | THE SOFTWARE. 38 | 39 | License 40 | MIT 41 | Title 42 | Hero 43 | Type 44 | PSGroupSpecifier 45 | 46 | 47 | FooterText 48 | Generated by CocoaPods - https://cocoapods.org 49 | Title 50 | 51 | Type 52 | PSGroupSpecifier 53 | 54 | 55 | StringsTable 56 | Acknowledgements 57 | Title 58 | Acknowledgements 59 | 60 | 61 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-MMPullSwipeDismiss/Pods-MMPullSwipeDismiss-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_MMPullSwipeDismiss : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_MMPullSwipeDismiss 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-MMPullSwipeDismiss/Pods-MMPullSwipeDismiss-frameworks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 5 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 6 | 7 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" 8 | 9 | install_framework() 10 | { 11 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 12 | local source="${BUILT_PRODUCTS_DIR}/$1" 13 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 14 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 15 | elif [ -r "$1" ]; then 16 | local source="$1" 17 | fi 18 | 19 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 20 | 21 | if [ -L "${source}" ]; then 22 | echo "Symlinked..." 23 | source="$(readlink "${source}")" 24 | fi 25 | 26 | # use filter instead of exclude so missing patterns dont' throw errors 27 | echo "rsync -av --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 28 | rsync -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 29 | 30 | local basename 31 | basename="$(basename -s .framework "$1")" 32 | binary="${destination}/${basename}.framework/${basename}" 33 | if ! [ -r "$binary" ]; then 34 | binary="${destination}/${basename}" 35 | fi 36 | 37 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 38 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 39 | strip_invalid_archs "$binary" 40 | fi 41 | 42 | # Resign the code if required by the build settings to avoid unstable apps 43 | code_sign_if_enabled "${destination}/$(basename "$1")" 44 | 45 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 46 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 47 | local swift_runtime_libs 48 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) 49 | for lib in $swift_runtime_libs; do 50 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 51 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 52 | code_sign_if_enabled "${destination}/${lib}" 53 | done 54 | fi 55 | } 56 | 57 | # Signs a framework with the provided identity 58 | code_sign_if_enabled() { 59 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 60 | # Use the current code_sign_identitiy 61 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 62 | local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements '$1'" 63 | 64 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 65 | code_sign_cmd="$code_sign_cmd &" 66 | fi 67 | echo "$code_sign_cmd" 68 | eval "$code_sign_cmd" 69 | fi 70 | } 71 | 72 | # Strip invalid architectures 73 | strip_invalid_archs() { 74 | binary="$1" 75 | # Get architectures for current file 76 | archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)" 77 | stripped="" 78 | for arch in $archs; do 79 | if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then 80 | # Strip non-valid architectures in-place 81 | lipo -remove "$arch" -output "$binary" "$binary" || exit 1 82 | stripped="$stripped $arch" 83 | fi 84 | done 85 | if [[ "$stripped" ]]; then 86 | echo "Stripped $binary of architectures:$stripped" 87 | fi 88 | } 89 | 90 | 91 | if [[ "$CONFIGURATION" == "Debug" ]]; then 92 | install_framework "$BUILT_PRODUCTS_DIR/Hero/Hero.framework" 93 | fi 94 | if [[ "$CONFIGURATION" == "Release" ]]; then 95 | install_framework "$BUILT_PRODUCTS_DIR/Hero/Hero.framework" 96 | fi 97 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 98 | wait 99 | fi 100 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-MMPullSwipeDismiss/Pods-MMPullSwipeDismiss-resources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 5 | 6 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt 7 | > "$RESOURCES_TO_COPY" 8 | 9 | XCASSET_FILES=() 10 | 11 | case "${TARGETED_DEVICE_FAMILY}" in 12 | 1,2) 13 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" 14 | ;; 15 | 1) 16 | TARGET_DEVICE_ARGS="--target-device iphone" 17 | ;; 18 | 2) 19 | TARGET_DEVICE_ARGS="--target-device ipad" 20 | ;; 21 | 3) 22 | TARGET_DEVICE_ARGS="--target-device tv" 23 | ;; 24 | 4) 25 | TARGET_DEVICE_ARGS="--target-device watch" 26 | ;; 27 | *) 28 | TARGET_DEVICE_ARGS="--target-device mac" 29 | ;; 30 | esac 31 | 32 | install_resource() 33 | { 34 | if [[ "$1" = /* ]] ; then 35 | RESOURCE_PATH="$1" 36 | else 37 | RESOURCE_PATH="${PODS_ROOT}/$1" 38 | fi 39 | if [[ ! -e "$RESOURCE_PATH" ]] ; then 40 | cat << EOM 41 | error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. 42 | EOM 43 | exit 1 44 | fi 45 | case $RESOURCE_PATH in 46 | *.storyboard) 47 | 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}" 48 | 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} 49 | ;; 50 | *.xib) 51 | 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}" 52 | 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} 53 | ;; 54 | *.framework) 55 | echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 56 | mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 57 | echo "rsync -av $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 58 | rsync -av "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 59 | ;; 60 | *.xcdatamodel) 61 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" 62 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" 63 | ;; 64 | *.xcdatamodeld) 65 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" 66 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" 67 | ;; 68 | *.xcmappingmodel) 69 | echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" 70 | xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" 71 | ;; 72 | *.xcassets) 73 | ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH" 74 | XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") 75 | ;; 76 | *) 77 | echo "$RESOURCE_PATH" 78 | echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" 79 | ;; 80 | esac 81 | } 82 | 83 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 84 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 85 | if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then 86 | mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 87 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 88 | fi 89 | rm -f "$RESOURCES_TO_COPY" 90 | 91 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ] 92 | then 93 | # Find all other xcassets (this unfortunately includes those of path pods and other targets). 94 | OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) 95 | while read line; do 96 | if [[ $line != "${PODS_ROOT}*" ]]; then 97 | XCASSET_FILES+=("$line") 98 | fi 99 | done <<<"$OTHER_XCASSETS" 100 | 101 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 102 | fi 103 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-MMPullSwipeDismiss/Pods-MMPullSwipeDismiss-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_MMPullSwipeDismissVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_MMPullSwipeDismissVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-MMPullSwipeDismiss/Pods-MMPullSwipeDismiss.debug.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/Hero" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 5 | OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/Hero/Hero.framework/Headers" 6 | OTHER_LDFLAGS = $(inherited) -framework "Hero" 7 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 8 | PODS_BUILD_DIR = $BUILD_DIR 9 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-MMPullSwipeDismiss/Pods-MMPullSwipeDismiss.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_MMPullSwipeDismiss { 2 | umbrella header "Pods-MMPullSwipeDismiss-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-MMPullSwipeDismiss/Pods-MMPullSwipeDismiss.release.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/Hero" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 5 | OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/Hero/Hero.framework/Headers" 6 | OTHER_LDFLAGS = $(inherited) -framework "Hero" 7 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 8 | PODS_BUILD_DIR = $BUILD_DIR 9 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-MMPullSwipeDismissTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-MMPullSwipeDismissTests/Pods-MMPullSwipeDismissTests-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | Generated by CocoaPods - https://cocoapods.org 4 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-MMPullSwipeDismissTests/Pods-MMPullSwipeDismissTests-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | Generated by CocoaPods - https://cocoapods.org 18 | Title 19 | 20 | Type 21 | PSGroupSpecifier 22 | 23 | 24 | StringsTable 25 | Acknowledgements 26 | Title 27 | Acknowledgements 28 | 29 | 30 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-MMPullSwipeDismissTests/Pods-MMPullSwipeDismissTests-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_MMPullSwipeDismissTests : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_MMPullSwipeDismissTests 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-MMPullSwipeDismissTests/Pods-MMPullSwipeDismissTests-frameworks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 5 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 6 | 7 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" 8 | 9 | install_framework() 10 | { 11 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 12 | local source="${BUILT_PRODUCTS_DIR}/$1" 13 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 14 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 15 | elif [ -r "$1" ]; then 16 | local source="$1" 17 | fi 18 | 19 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 20 | 21 | if [ -L "${source}" ]; then 22 | echo "Symlinked..." 23 | source="$(readlink "${source}")" 24 | fi 25 | 26 | # use filter instead of exclude so missing patterns dont' throw errors 27 | echo "rsync -av --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 28 | rsync -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 29 | 30 | local basename 31 | basename="$(basename -s .framework "$1")" 32 | binary="${destination}/${basename}.framework/${basename}" 33 | if ! [ -r "$binary" ]; then 34 | binary="${destination}/${basename}" 35 | fi 36 | 37 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 38 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 39 | strip_invalid_archs "$binary" 40 | fi 41 | 42 | # Resign the code if required by the build settings to avoid unstable apps 43 | code_sign_if_enabled "${destination}/$(basename "$1")" 44 | 45 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 46 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 47 | local swift_runtime_libs 48 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) 49 | for lib in $swift_runtime_libs; do 50 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 51 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 52 | code_sign_if_enabled "${destination}/${lib}" 53 | done 54 | fi 55 | } 56 | 57 | # Signs a framework with the provided identity 58 | code_sign_if_enabled() { 59 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 60 | # Use the current code_sign_identitiy 61 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 62 | local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements '$1'" 63 | 64 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 65 | code_sign_cmd="$code_sign_cmd &" 66 | fi 67 | echo "$code_sign_cmd" 68 | eval "$code_sign_cmd" 69 | fi 70 | } 71 | 72 | # Strip invalid architectures 73 | strip_invalid_archs() { 74 | binary="$1" 75 | # Get architectures for current file 76 | archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)" 77 | stripped="" 78 | for arch in $archs; do 79 | if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then 80 | # Strip non-valid architectures in-place 81 | lipo -remove "$arch" -output "$binary" "$binary" || exit 1 82 | stripped="$stripped $arch" 83 | fi 84 | done 85 | if [[ "$stripped" ]]; then 86 | echo "Stripped $binary of architectures:$stripped" 87 | fi 88 | } 89 | 90 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 91 | wait 92 | fi 93 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-MMPullSwipeDismissTests/Pods-MMPullSwipeDismissTests-resources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 5 | 6 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt 7 | > "$RESOURCES_TO_COPY" 8 | 9 | XCASSET_FILES=() 10 | 11 | case "${TARGETED_DEVICE_FAMILY}" in 12 | 1,2) 13 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" 14 | ;; 15 | 1) 16 | TARGET_DEVICE_ARGS="--target-device iphone" 17 | ;; 18 | 2) 19 | TARGET_DEVICE_ARGS="--target-device ipad" 20 | ;; 21 | 3) 22 | TARGET_DEVICE_ARGS="--target-device tv" 23 | ;; 24 | 4) 25 | TARGET_DEVICE_ARGS="--target-device watch" 26 | ;; 27 | *) 28 | TARGET_DEVICE_ARGS="--target-device mac" 29 | ;; 30 | esac 31 | 32 | install_resource() 33 | { 34 | if [[ "$1" = /* ]] ; then 35 | RESOURCE_PATH="$1" 36 | else 37 | RESOURCE_PATH="${PODS_ROOT}/$1" 38 | fi 39 | if [[ ! -e "$RESOURCE_PATH" ]] ; then 40 | cat << EOM 41 | error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. 42 | EOM 43 | exit 1 44 | fi 45 | case $RESOURCE_PATH in 46 | *.storyboard) 47 | 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}" 48 | 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} 49 | ;; 50 | *.xib) 51 | 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}" 52 | 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} 53 | ;; 54 | *.framework) 55 | echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 56 | mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 57 | echo "rsync -av $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 58 | rsync -av "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 59 | ;; 60 | *.xcdatamodel) 61 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" 62 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" 63 | ;; 64 | *.xcdatamodeld) 65 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" 66 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" 67 | ;; 68 | *.xcmappingmodel) 69 | echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" 70 | xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" 71 | ;; 72 | *.xcassets) 73 | ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH" 74 | XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") 75 | ;; 76 | *) 77 | echo "$RESOURCE_PATH" 78 | echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" 79 | ;; 80 | esac 81 | } 82 | 83 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 84 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 85 | if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then 86 | mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 87 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 88 | fi 89 | rm -f "$RESOURCES_TO_COPY" 90 | 91 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ] 92 | then 93 | # Find all other xcassets (this unfortunately includes those of path pods and other targets). 94 | OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) 95 | while read line; do 96 | if [[ $line != "${PODS_ROOT}*" ]]; then 97 | XCASSET_FILES+=("$line") 98 | fi 99 | done <<<"$OTHER_XCASSETS" 100 | 101 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 102 | fi 103 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-MMPullSwipeDismissTests/Pods-MMPullSwipeDismissTests-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_MMPullSwipeDismissTestsVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_MMPullSwipeDismissTestsVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-MMPullSwipeDismissTests/Pods-MMPullSwipeDismissTests.debug.xcconfig: -------------------------------------------------------------------------------- 1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/Hero" 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 4 | OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/Hero/Hero.framework/Headers" 5 | PODS_BUILD_DIR = $BUILD_DIR 6 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 8 | PODS_ROOT = ${SRCROOT}/Pods 9 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-MMPullSwipeDismissTests/Pods-MMPullSwipeDismissTests.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_MMPullSwipeDismissTests { 2 | umbrella header "Pods-MMPullSwipeDismissTests-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-MMPullSwipeDismissTests/Pods-MMPullSwipeDismissTests.release.xcconfig: -------------------------------------------------------------------------------- 1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/Hero" 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 4 | OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/Hero/Hero.framework/Headers" 5 | PODS_BUILD_DIR = $BUILD_DIR 6 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 8 | PODS_ROOT = ${SRCROOT}/Pods 9 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-MMPullSwipeDismissUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-MMPullSwipeDismissUITests/Pods-MMPullSwipeDismissUITests-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | Generated by CocoaPods - https://cocoapods.org 4 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-MMPullSwipeDismissUITests/Pods-MMPullSwipeDismissUITests-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | Generated by CocoaPods - https://cocoapods.org 18 | Title 19 | 20 | Type 21 | PSGroupSpecifier 22 | 23 | 24 | StringsTable 25 | Acknowledgements 26 | Title 27 | Acknowledgements 28 | 29 | 30 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-MMPullSwipeDismissUITests/Pods-MMPullSwipeDismissUITests-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_MMPullSwipeDismissUITests : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_MMPullSwipeDismissUITests 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-MMPullSwipeDismissUITests/Pods-MMPullSwipeDismissUITests-frameworks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 5 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 6 | 7 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" 8 | 9 | install_framework() 10 | { 11 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 12 | local source="${BUILT_PRODUCTS_DIR}/$1" 13 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 14 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 15 | elif [ -r "$1" ]; then 16 | local source="$1" 17 | fi 18 | 19 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 20 | 21 | if [ -L "${source}" ]; then 22 | echo "Symlinked..." 23 | source="$(readlink "${source}")" 24 | fi 25 | 26 | # use filter instead of exclude so missing patterns dont' throw errors 27 | echo "rsync -av --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 28 | rsync -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 29 | 30 | local basename 31 | basename="$(basename -s .framework "$1")" 32 | binary="${destination}/${basename}.framework/${basename}" 33 | if ! [ -r "$binary" ]; then 34 | binary="${destination}/${basename}" 35 | fi 36 | 37 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 38 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 39 | strip_invalid_archs "$binary" 40 | fi 41 | 42 | # Resign the code if required by the build settings to avoid unstable apps 43 | code_sign_if_enabled "${destination}/$(basename "$1")" 44 | 45 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 46 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 47 | local swift_runtime_libs 48 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) 49 | for lib in $swift_runtime_libs; do 50 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 51 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 52 | code_sign_if_enabled "${destination}/${lib}" 53 | done 54 | fi 55 | } 56 | 57 | # Signs a framework with the provided identity 58 | code_sign_if_enabled() { 59 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 60 | # Use the current code_sign_identitiy 61 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 62 | local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements '$1'" 63 | 64 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 65 | code_sign_cmd="$code_sign_cmd &" 66 | fi 67 | echo "$code_sign_cmd" 68 | eval "$code_sign_cmd" 69 | fi 70 | } 71 | 72 | # Strip invalid architectures 73 | strip_invalid_archs() { 74 | binary="$1" 75 | # Get architectures for current file 76 | archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)" 77 | stripped="" 78 | for arch in $archs; do 79 | if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then 80 | # Strip non-valid architectures in-place 81 | lipo -remove "$arch" -output "$binary" "$binary" || exit 1 82 | stripped="$stripped $arch" 83 | fi 84 | done 85 | if [[ "$stripped" ]]; then 86 | echo "Stripped $binary of architectures:$stripped" 87 | fi 88 | } 89 | 90 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 91 | wait 92 | fi 93 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-MMPullSwipeDismissUITests/Pods-MMPullSwipeDismissUITests-resources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 5 | 6 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt 7 | > "$RESOURCES_TO_COPY" 8 | 9 | XCASSET_FILES=() 10 | 11 | case "${TARGETED_DEVICE_FAMILY}" in 12 | 1,2) 13 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" 14 | ;; 15 | 1) 16 | TARGET_DEVICE_ARGS="--target-device iphone" 17 | ;; 18 | 2) 19 | TARGET_DEVICE_ARGS="--target-device ipad" 20 | ;; 21 | 3) 22 | TARGET_DEVICE_ARGS="--target-device tv" 23 | ;; 24 | 4) 25 | TARGET_DEVICE_ARGS="--target-device watch" 26 | ;; 27 | *) 28 | TARGET_DEVICE_ARGS="--target-device mac" 29 | ;; 30 | esac 31 | 32 | install_resource() 33 | { 34 | if [[ "$1" = /* ]] ; then 35 | RESOURCE_PATH="$1" 36 | else 37 | RESOURCE_PATH="${PODS_ROOT}/$1" 38 | fi 39 | if [[ ! -e "$RESOURCE_PATH" ]] ; then 40 | cat << EOM 41 | error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. 42 | EOM 43 | exit 1 44 | fi 45 | case $RESOURCE_PATH in 46 | *.storyboard) 47 | 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}" 48 | 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} 49 | ;; 50 | *.xib) 51 | 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}" 52 | 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} 53 | ;; 54 | *.framework) 55 | echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 56 | mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 57 | echo "rsync -av $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 58 | rsync -av "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 59 | ;; 60 | *.xcdatamodel) 61 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" 62 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" 63 | ;; 64 | *.xcdatamodeld) 65 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" 66 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" 67 | ;; 68 | *.xcmappingmodel) 69 | echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" 70 | xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" 71 | ;; 72 | *.xcassets) 73 | ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH" 74 | XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") 75 | ;; 76 | *) 77 | echo "$RESOURCE_PATH" 78 | echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" 79 | ;; 80 | esac 81 | } 82 | 83 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 84 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 85 | if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then 86 | mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 87 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 88 | fi 89 | rm -f "$RESOURCES_TO_COPY" 90 | 91 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ] 92 | then 93 | # Find all other xcassets (this unfortunately includes those of path pods and other targets). 94 | OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) 95 | while read line; do 96 | if [[ $line != "${PODS_ROOT}*" ]]; then 97 | XCASSET_FILES+=("$line") 98 | fi 99 | done <<<"$OTHER_XCASSETS" 100 | 101 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 102 | fi 103 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-MMPullSwipeDismissUITests/Pods-MMPullSwipeDismissUITests-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_MMPullSwipeDismissUITestsVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_MMPullSwipeDismissUITestsVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-MMPullSwipeDismissUITests/Pods-MMPullSwipeDismissUITests.debug.xcconfig: -------------------------------------------------------------------------------- 1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/Hero" 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 4 | OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/Hero/Hero.framework/Headers" 5 | PODS_BUILD_DIR = $BUILD_DIR 6 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 8 | PODS_ROOT = ${SRCROOT}/Pods 9 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-MMPullSwipeDismissUITests/Pods-MMPullSwipeDismissUITests.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_MMPullSwipeDismissUITests { 2 | umbrella header "Pods-MMPullSwipeDismissUITests-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-MMPullSwipeDismissUITests/Pods-MMPullSwipeDismissUITests.release.xcconfig: -------------------------------------------------------------------------------- 1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/Hero" 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 4 | OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/Hero/Hero.framework/Headers" 5 | PODS_BUILD_DIR = $BUILD_DIR 6 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 8 | PODS_ROOT = ${SRCROOT}/Pods 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MMPullSwipeDismiss 2 | 3 | Facebook Like Swipe and On scroll Pull Dismiss Viewcontroller 4 | 5 | ### Medium Article on how to use this in your project 6 | https://medium.com/@mandoramuku07/how-to-create-facebook-like-swipe-pulltodismiss-5480b186f809 7 | 8 | Requirements 9 | ----------------- 10 | * Swift 4.0+ 11 | * Xcode 9 12 | * iOS 9.0+ 13 | 14 | #### The demo also consist example with Navigation bar please check `PullSwipeExUtil` and `MMPullSwipeDismissViewController` file 15 | 16 | ## Demo Swipe Left 17 | ![MMPullSwipeDismiss](https://github.com/mukyasa/MMPullSwipeDismiss/blob/master/MMPullSwipeDismiss/demomaster_swipealeft.gif)
18 | 19 | ## Demo Pull Up 20 | ![MMPullSwipeDismiss](https://github.com/mukyasa/MMPullSwipeDismiss/blob/master/MMPullSwipeDismiss/demomaster_swipebup.gif)
21 | 22 | ## Demo Pull Down 23 | ![MMPullSwipeDismiss](https://github.com/mukyasa/MMPullSwipeDismiss/blob/master/MMPullSwipeDismiss/demomaster_swipedown.gif)
24 | 25 | # Download run and check the demo 26 | 27 | Contact Me 28 | ========== 29 | Mukesh Mandora 30 | 31 | Contact: mandoramuku07@gmail.com 32 | 33 | Twitter: http://twitter.com/mandymuku 34 | 35 | LinkedIn: https://in.linkedin.com/in/mukeshmandora 36 | 37 | Github:https://github.com/mukyasa 38 | --------------------------------------------------------------------------------