No Description

NavigationController.swift 4.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. //
  2. // NavigationController.swift
  3. // PaiaiUIKit
  4. //
  5. // Created by FFIB on 2019/4/23.
  6. // Copyright © 2019 FFIB. All rights reserved.
  7. //
  8. import UIKit
  9. public class NavigationController: UINavigationController {
  10. override public init(rootViewController: UIViewController) {
  11. super.init(navigationBarClass: NavigationBar.classForCoder(), toolbarClass: nil)
  12. self.viewControllers = [rootViewController]
  13. }
  14. required init?(coder aDecoder: NSCoder) {
  15. super.init(coder: aDecoder)
  16. }
  17. override public init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
  18. super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
  19. }
  20. override public func viewDidLoad() {
  21. super.viewDidLoad()
  22. delegate = self
  23. interactivePopGestureRecognizer?.delegate = self
  24. interactivePopGestureRecognizer?.isEnabled = true
  25. interactivePopGestureRecognizer?.addTarget(self,
  26. action: #selector(handlePop(gestureRecognizer:)))
  27. }
  28. @objc
  29. private func handlePop(gestureRecognizer: UIPanGestureRecognizer) {
  30. guard let navBar = navigationBar as? NavigationBar else { return }
  31. if gestureRecognizer.state == .began { navBar.isPush = false }
  32. guard navBar.needsInteractive else { return }
  33. let percent = gestureRecognizer.translation(in: view).x / view.bounds.width
  34. if gestureRecognizer.state == .began || gestureRecognizer.state == .changed {
  35. navBar.transitionAnimationWithPercent(percent)
  36. }
  37. guard gestureRecognizer.state == .ended
  38. || gestureRecognizer.state == .cancelled
  39. || gestureRecognizer.state == .failed,
  40. let coordinator = transitionCoordinator else { return }
  41. navBar.bounce = percent < 0.5 ? .backward : .forward
  42. let durationPercent = Double(percent < 0.5 ? coordinator.percentComplete : (1 - coordinator.percentComplete))
  43. UIView.animate(withDuration: coordinator.transitionDuration * durationPercent,
  44. delay: 0,
  45. usingSpringWithDamping: 1,
  46. initialSpringVelocity: coordinator.completionVelocity,
  47. options: [],
  48. animations: {
  49. navBar.transitionAnimationWithPercent(1)
  50. }, completion: { _ in
  51. navBar.clear()
  52. })
  53. }
  54. }
  55. extension NavigationController: UINavigationControllerDelegate {
  56. public func navigationController(_ navigationController: UINavigationController,
  57. animationControllerFor operation: UINavigationController.Operation,
  58. from fromVC: UIViewController,
  59. to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
  60. (navigationBar as? NavigationBar)?.isPush = operation == .push
  61. return nil
  62. }
  63. public func navigationController(_ navigationController: UINavigationController,
  64. willShow viewController: UIViewController,
  65. animated: Bool) {
  66. guard let navBar = navigationBar as? NavigationBar,
  67. navBar.needsInteractive else { return }
  68. guard let coordinator = transitionCoordinator,
  69. animated else {
  70. navBar.setBackgroundImage()
  71. navBar.clear()
  72. return
  73. }
  74. navBar.constructViewHierarchy()
  75. guard !coordinator.isInteractive else { return }
  76. coordinator.animate(alongsideTransition: { (transitionContext) in
  77. DispatchQueue.main.async {
  78. UIView.beginAnimations(nil, context: nil)
  79. UIView.setAnimationCurve(transitionContext.completionCurve)
  80. UIView.setAnimationDuration(transitionContext.transitionDuration)
  81. navBar.transitionAnimation()
  82. UIView.commitAnimations()
  83. }
  84. }, completion: { (_) in
  85. navBar.clear()
  86. })
  87. }
  88. }
  89. extension NavigationController: UIGestureRecognizerDelegate {
  90. public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
  91. if gestureRecognizer == interactivePopGestureRecognizer {
  92. return viewControllers.count > 1
  93. }
  94. return true
  95. }
  96. }