GYSideAnimatedTransitioning.swift 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. //
  2. // GYSideAnimatedTransitioning.swift
  3. // GYSide
  4. //
  5. // Created by gaoyuan on 2018/1/29.
  6. // Copyright © 2018年 gaoyuan. All rights reserved.
  7. //
  8. import UIKit
  9. enum GYSideShowType:Int {
  10. case show,hidden
  11. }
  12. class GYSideAnimatedTransitioning: NSObject,UIViewControllerAnimatedTransitioning {
  13. var type:GYSideShowType!
  14. var config:GYSideConfig!
  15. init(showType: GYSideShowType,config: GYSideConfig) {
  16. super.init()
  17. type = showType
  18. self.config = config
  19. }
  20. // 执行的动画时长
  21. func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
  22. return config.timeInterval;
  23. }
  24. func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
  25. switch type {
  26. case .show?:
  27. animateTransitionShowType(transitionContext: transitionContext)
  28. break
  29. case .hidden?:
  30. animateTransitionHiddenType(transitionContext: transitionContext)
  31. break
  32. default:
  33. break
  34. }
  35. }
  36. // show
  37. func animateTransitionShowType(transitionContext: UIViewControllerContextTransitioning) {
  38. let fromController: UIViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from)!
  39. let toController: UIViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to)!
  40. let containerView = transitionContext.containerView
  41. let width:CGFloat = (UIApplication.shared.keyWindow?.bounds.size.width)! * self.config.sideRelative
  42. let x:CGFloat! = config.direction == .left ? 0.0 : ((UIApplication.shared.keyWindow?.bounds.size.width)! - width)
  43. toController.view.frame = CGRect.init(x: x, y: 0, width: width, height: containerView.frame.height)
  44. toController.view.clipsToBounds = true
  45. // fromController UINavigationController
  46. // toController SnapKitViewController
  47. containerView.addSubview(toController.view)
  48. containerView.addSubview(fromController.view)
  49. var mask:GYSideMaskView?
  50. for view in toController.view.subviews {
  51. if view.isKind(of: GYSideMaskView.classForCoder()){
  52. mask = view as? GYSideMaskView
  53. break
  54. }
  55. }
  56. if mask == nil {
  57. mask = GYSideMaskView()
  58. fromController.view.addSubview(mask!)
  59. }
  60. mask?.frame = fromController.view.bounds
  61. mask?.alpha = 0.0
  62. mask?.isUserInteractionEnabled = false
  63. let flag: CGFloat! = config.direction == .left ? -1.0 : 1.0
  64. var fromTransform: CGAffineTransform = CGAffineTransform.init(translationX: -flag * width, y: 0)
  65. let toTransform: CGAffineTransform = CGAffineTransform.init(translationX: flag * width, y: 0)
  66. if self.config.animationType == .translationMask {
  67. fromTransform = CGAffineTransform.init(translationX: 0, y: 0)
  68. containerView.bringSubviewToFront(toController.view)
  69. }else if self.config.animationType == .zoom {
  70. let t1: CGAffineTransform = CGAffineTransform.init(translationX: -flag * width * config.zoomOffsetRelative, y: 0)
  71. let t2: CGAffineTransform = CGAffineTransform.init(scaleX: config.zoomRelative, y: config.zoomRelative)
  72. fromTransform = t1.concatenating(t2)
  73. }
  74. if self.config.animationType != .zoom {
  75. toController.view.transform = toTransform
  76. toController.view.frame = CGRect.init(x: toTransform.tx+x, y: 0, width: width, height: containerView.frame.height)
  77. }else {
  78. toController.view.transform = CGAffineTransform.init(translationX: 0, y: 0)
  79. toController.view.frame = CGRect.init(x: 0, y: 0, width: width, height: containerView.frame.height)
  80. }
  81. UIView.animate(withDuration: self.transitionDuration(using: transitionContext), animations: {
  82. mask?.alpha = self.config.maskAlpha
  83. toController.view.transform = .identity
  84. fromController.view.transform = fromTransform
  85. }) { (finished) in
  86. if !transitionContext.transitionWasCancelled {
  87. mask?.isUserInteractionEnabled = true
  88. transitionContext.completeTransition(true)
  89. containerView.addSubview(fromController.view)
  90. if self.config.animationType == .translationMask {
  91. containerView.bringSubviewToFront(toController.view)
  92. }
  93. }else {
  94. mask?.destroy()
  95. toController.view.transform = toTransform;
  96. fromController.view.frame = containerView.frame;
  97. transitionContext.completeTransition(false)
  98. }
  99. }
  100. }
  101. // hidde
  102. func animateTransitionHiddenType(transitionContext: UIViewControllerContextTransitioning) {
  103. let fromController:UIViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from)!
  104. let toController:UIViewController = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to)!
  105. let containerView = transitionContext.containerView
  106. let width:CGFloat = (UIApplication.shared.keyWindow?.bounds.size.width)! * self.config.sideRelative
  107. let x:CGFloat! = config.direction == .left ? 0.0 : ((UIApplication.shared.keyWindow?.bounds.size.width)! - width)
  108. fromController.view.frame = CGRect.init(x: x, y: 0, width: width, height: containerView.frame.height)
  109. var mask:GYSideMaskView?
  110. for view in toController.view.subviews {
  111. if view.isKind(of: GYSideMaskView.classForCoder()){
  112. mask = view as? GYSideMaskView
  113. break
  114. }
  115. }
  116. let flag: CGFloat! = config.direction == GYSideDirection.left ? -1.0 : 1.0
  117. var fromTransform:CGAffineTransform = CGAffineTransform.init(translationX: flag * width, y: 0)
  118. if self.config.animationType == .translationMask {
  119. fromTransform = CGAffineTransform.init(translationX: flag * width, y: 0)
  120. }else if self.config.animationType == .zoom {
  121. fromTransform = CGAffineTransform.init(translationX: 0, y: 0)
  122. containerView.bringSubviewToFront(toController.view)
  123. }
  124. UIView.animate(withDuration: self.transitionDuration(using: transitionContext), animations: {
  125. mask?.alpha = 0.001
  126. fromController.view.transform = fromTransform
  127. toController.view.transform = .identity
  128. }) { (finished) in
  129. transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
  130. if !transitionContext.transitionWasCancelled {
  131. mask?.destroy()
  132. }else {
  133. if self.config.animationType != .zoom {
  134. containerView.bringSubviewToFront(fromController.view)
  135. }
  136. }
  137. }
  138. }
  139. deinit {
  140. // print( NSStringFromClass(self.classForCoder) + " 销毁了---->4")
  141. }
  142. }