ContainerTransition.swift 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. //
  2. // Created by Tom Baranes on 06/05/16.
  3. // Copyright © 2016 IBAnimatable. All rights reserved.
  4. //
  5. import UIKit
  6. public class ContainerTransition: NSObject {
  7. public typealias ContainerTransitionCompletion = () -> Void
  8. // MARK: Properties
  9. public var animationType: TransitionAnimationType?
  10. public var transitionDuration: Duration = defaultTransitionDuration
  11. // MARK: Private
  12. fileprivate let container: UIView?
  13. fileprivate let parentViewController: UIViewController?
  14. fileprivate var viewControllers: [UITransitionContextViewControllerKey: UIViewController]?
  15. fileprivate var views: [UITransitionContextViewKey: UIView]?
  16. fileprivate let completion: ContainerTransitionCompletion?
  17. // MARK: Life cycle
  18. public init(animationType: TransitionAnimationType,
  19. container: UIView,
  20. parentViewController: UIViewController,
  21. fromViewController: UIViewController?,
  22. toViewController: UIViewController,
  23. completion: ContainerTransitionCompletion? = nil) {
  24. self.completion = completion
  25. self.animationType = animationType
  26. self.container = container
  27. self.parentViewController = parentViewController
  28. container.translatesAutoresizingMaskIntoConstraints = false
  29. toViewController.view.translatesAutoresizingMaskIntoConstraints = true
  30. toViewController.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
  31. toViewController.view.frame = container.bounds
  32. fromViewController?.willMove(toParent: nil)
  33. parentViewController.addChild(toViewController)
  34. guard let fromViewController = fromViewController else {
  35. container.addSubview(toViewController.view)
  36. toViewController.didMove(toParent: parentViewController)
  37. completion?()
  38. return
  39. }
  40. viewControllers = [UITransitionContextViewControllerKey.from: fromViewController,
  41. UITransitionContextViewControllerKey.to: toViewController]
  42. views = [UITransitionContextViewKey.from: fromViewController.view,
  43. UITransitionContextViewKey.to: toViewController.view]
  44. }
  45. public func animate() {
  46. guard let animationType = animationType else {
  47. return
  48. }
  49. parentViewController?.view.isUserInteractionEnabled = false
  50. let animator = AnimatorFactory.makeAnimator(transitionAnimationType: animationType)
  51. animator?.transitionDuration = transitionDuration
  52. animator?.animateTransition(using: self)
  53. }
  54. public var isAnimated: Bool { return false }
  55. public var isInteractive: Bool { return false }
  56. public var presentationStyle: UIModalPresentationStyle { return .none }
  57. public var transitionWasCancelled: Bool { return false }
  58. public var targetTransform: CGAffineTransform { return .identity }
  59. public var containerView: UIView { return container! }
  60. }
  61. // MARK: - UIViewControllerContextTransitioning
  62. extension ContainerTransition: UIViewControllerContextTransitioning {
  63. public func viewController(forKey key: UITransitionContextViewControllerKey) -> UIViewController? {
  64. return viewControllers?[key]
  65. }
  66. public func view(forKey key: UITransitionContextViewKey) -> UIView? {
  67. return views?[key]
  68. }
  69. public func completeTransition(_ didComplete: Bool) {
  70. viewControllers?[UITransitionContextViewControllerKey.from]?.view.removeFromSuperview()
  71. viewControllers?[UITransitionContextViewControllerKey.from]?.removeFromParent()
  72. viewControllers?[UITransitionContextViewControllerKey.to]?.didMove(toParent: parentViewController)
  73. parentViewController?.view.isUserInteractionEnabled = true
  74. completion?()
  75. }
  76. public func initialFrame(for vc: UIViewController) -> CGRect {
  77. return vc.view.frame
  78. }
  79. public func finalFrame(for vc: UIViewController) -> CGRect {
  80. return vc.view.frame
  81. }
  82. // MARK: Mandatory protocol
  83. public func updateInteractiveTransition(_ percentComplete: CGFloat) {}
  84. public func finishInteractiveTransition() {}
  85. public func cancelInteractiveTransition() {}
  86. public func pauseInteractiveTransition() {}
  87. }