SystemTransitionAnimator.swift 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. //
  2. // SystemTransitionAnimator.swift
  3. // IBAnimatable
  4. //
  5. // Created by Steven on 4/1/17.
  6. // Copyright © 2017 IBAnimatable. All rights reserved.
  7. //
  8. import UIKit
  9. class SystemTransitionAnimator: NSObject, AnimatedTransitioning {
  10. var transitionDuration: Duration
  11. var transitionAnimationType: TransitionAnimationType
  12. var reverseAnimationType: TransitionAnimationType?
  13. var interactiveGestureType: InteractiveGestureType?
  14. var systemTransitionType: TransitionAnimationType.SystemTransitionType
  15. var systemTransitionSubtype: CATransitionSubtype?
  16. init(systemType: TransitionAnimationType.SystemTransitionType, duration: Duration) {
  17. systemTransitionType = systemType
  18. transitionDuration = duration
  19. transitionAnimationType = TransitionAnimationType(systemType: systemType)
  20. reverseAnimationType = transitionAnimationType.reversed
  21. systemTransitionSubtype = nil
  22. super.init()
  23. }
  24. init(systemType: TransitionAnimationType.SystemTransitionType, duration: Duration, direction: TransitionAnimationType.Direction) {
  25. transitionAnimationType = TransitionAnimationType(systemType: systemType, direction: direction)
  26. reverseAnimationType = transitionAnimationType.reversed
  27. transitionDuration = duration
  28. systemTransitionType = systemType
  29. switch systemType {
  30. case .cube, .flip, .moveIn, .push, .reveal:
  31. systemTransitionSubtype = direction.caTransitionSubtype
  32. interactiveGestureType = .pan(from: direction.opposingGesture)
  33. case .cameraIrisHollowClose, .cameraIrisHollowOpen, .cameraIris:
  34. interactiveGestureType = .pinch(direction: direction.opposingGesture)
  35. case .pageUnCurl, .pageCurl:
  36. interactiveGestureType = .pan(from: direction.opposingGesture)
  37. default:
  38. fatalError("Should never be executed: use other SystemTranitionAnimator.init")
  39. }
  40. super.init()
  41. }
  42. // MARK: - Helper Methods (Private)
  43. fileprivate func performSystemTransition(using context: UIViewControllerContextTransitioning) {
  44. CALayer.animate({
  45. let transition = CATransition()
  46. #if swift(>=4.2)
  47. transition.type = CATransitionType(rawValue: systemTransitionType.rawValue)
  48. #else
  49. transition.type = systemTransitionType.rawValue
  50. #endif
  51. transition.subtype = systemTransitionSubtype
  52. transition.duration = transitionDuration(using: context)
  53. transition.timingFunctionType = .easeOutCubic
  54. context.containerView.layer.add(transition, forKey: kCATransition)
  55. }, completion: {
  56. context.completeTransition(!context.transitionWasCancelled)
  57. })
  58. }
  59. }
  60. extension SystemTransitionAnimator: UIViewControllerAnimatedTransitioning {
  61. func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
  62. return transitionContext?.isAnimated == true ? transitionDuration : 0
  63. }
  64. func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
  65. let toViewTemp = transitionContext.view(forKey: UITransitionContextViewKey.to)
  66. let fromViewTemp = transitionContext.view(forKey: UITransitionContextViewKey.from)
  67. let toViewControllerTemp = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to)
  68. guard let toView = toViewTemp, fromViewTemp != nil else {
  69. transitionContext.completeTransition(true)
  70. return
  71. }
  72. if let toViewController = toViewControllerTemp {
  73. toView.frame = transitionContext.finalFrame(for: toViewController)
  74. }
  75. transitionContext.containerView.addSubview(toView)
  76. performSystemTransition(using: transitionContext)
  77. }
  78. }