Advertisement
Guest User

Untitled

a guest
Feb 20th, 2019
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.45 KB | None | 0 0
  1. import UIKit
  2.  
  3. class ModalAnimationController: NSObject, UIViewControllerAnimatedTransitioning {
  4.  
  5. func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
  6. fatalError("Abstract method")
  7. }
  8.  
  9. let cornerRadius: CGFloat = 20
  10. let offset: CGFloat = 60
  11.  
  12. func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
  13. return 0.4
  14. }
  15.  
  16. }
  17.  
  18. final class ModalPresentAnimationController: ModalAnimationController {
  19.  
  20. override func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
  21. guard let fromVC = transitionContext.viewController(forKey: .from),
  22. let fromView = fromVC.view,
  23. let toVC = transitionContext.viewController(forKey: .to),
  24. let toView = toVC.view
  25. else {
  26. return
  27. }
  28.  
  29. let offset = self.offset
  30. let cornerRadius = self.cornerRadius
  31. let duration = transitionDuration(using: transitionContext)
  32. let containerView = transitionContext.containerView
  33.  
  34. let fromSnapshot = fromView.snapshotView(afterScreenUpdates: true)!
  35. containerView.addSubview(fromSnapshot)
  36. fromSnapshot.layer.masksToBounds = true
  37. fromView.removeFromSuperview()
  38.  
  39. containerView.addSubview(toView)
  40. toView.layer.cornerRadius = cornerRadius
  41. toView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
  42. toView.layer.masksToBounds = true
  43. toView.frame = CGRect(x: 0,
  44. y: offset,
  45. width: containerView.frame.width,
  46. height: containerView.frame.height - offset)
  47.  
  48. guard let toSnapshot = toView.snapshotView(afterScreenUpdates: true) else {
  49. return
  50. }
  51.  
  52. containerView.addSubview(toSnapshot)
  53. toSnapshot.layer.cornerRadius = cornerRadius
  54. toSnapshot.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
  55. toSnapshot.layer.masksToBounds = true
  56. toSnapshot.frame = CGRect(x: 0,
  57. y: containerView.frame.height,
  58. width: containerView.frame.width,
  59. height: containerView.frame.height - offset)
  60.  
  61. toView.isHidden = true
  62.  
  63. UIView.animate(withDuration: duration, delay: 0, options: [.curveEaseInOut], animations: {
  64. fromSnapshot.layer.cornerRadius = cornerRadius
  65. fromSnapshot.alpha = 0.5
  66. fromSnapshot.transform = CGAffineTransform(scaleX: 0.9, y: 0.9)
  67. toSnapshot.frame.origin.y = offset
  68. }) { _ in
  69. toView.isHidden = false
  70. toSnapshot.removeFromSuperview()
  71. transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
  72. }
  73. }
  74.  
  75. }
  76.  
  77. final class ModalDismissAnimationController: ModalAnimationController {
  78.  
  79. override func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
  80. guard let fromVC = transitionContext.viewController(forKey: .from),
  81. let fromView = fromVC.view,
  82. let toVC = transitionContext.viewController(forKey: .to),
  83. let toView = toVC.view
  84. else {
  85. return
  86. }
  87.  
  88. let offset = self.offset
  89. let duration = transitionDuration(using: transitionContext)
  90. let containerView = transitionContext.containerView
  91.  
  92. guard let fromSnapshot = fromView.snapshotView(afterScreenUpdates: true),
  93. let toSnapshot = containerView.subviews.first else {
  94. return
  95. }
  96.  
  97. containerView.addSubview(fromSnapshot)
  98. fromView.removeFromSuperview()
  99. fromSnapshot.frame = CGRect(x: 0,
  100. y: offset,
  101. width: containerView.frame.width,
  102. height: containerView.frame.height - offset)
  103.  
  104. toView.isHidden = true
  105.  
  106. UIView.animate(withDuration: duration, delay: 0, options: [.curveEaseInOut], animations: {
  107. fromSnapshot.frame.origin.y = containerView.frame.height
  108. toSnapshot.layer.cornerRadius = 0
  109. toSnapshot.alpha = 1
  110. toSnapshot.transform = CGAffineTransform.identity
  111. }) { _ in
  112. toView.isHidden = false
  113. transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
  114. }
  115. }
  116.  
  117. }
  118.  
  119. final class ModalViewController: UIViewController, UIViewControllerTransitioningDelegate {
  120.  
  121. override var preferredStatusBarStyle: UIStatusBarStyle {
  122. return .lightContent
  123. }
  124.  
  125. override func viewDidLoad() {
  126. super.viewDidLoad()
  127.  
  128. transitioningDelegate = self
  129. }
  130.  
  131. @IBAction func tapCloseModal(sender: UIButton) {
  132. dismiss(animated: true, completion: nil)
  133. }
  134.  
  135. }
  136.  
  137.  
  138. extension ModalViewController {
  139.  
  140. func animationController(forPresented presented: UIViewController,
  141. presenting: UIViewController,
  142. source: UIViewController)
  143. -> UIViewControllerAnimatedTransitioning? {
  144. return ModalPresentAnimationController()
  145. }
  146.  
  147. func animationController(forDismissed dismissed: UIViewController)
  148. -> UIViewControllerAnimatedTransitioning? {
  149. return ModalDismissAnimationController()
  150. }
  151.  
  152. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement