No Description

NavigationController.swift 4.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  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, delay: 0, usingSpringWithDamping: 1,
  44. initialSpringVelocity: coordinator.completionVelocity, options: [], animations: {
  45. navBar.transitionAnimationWithPercent(1)
  46. }) { _ in
  47. navBar.clear()
  48. }
  49. }
  50. }
  51. extension NavigationController: UINavigationControllerDelegate {
  52. public func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationController.Operation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
  53. (navigationBar as? NavigationBar)?.isPush = operation == .push
  54. return nil
  55. }
  56. public func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
  57. guard let navBar = navigationBar as? NavigationBar,
  58. navBar.needsInteractive else { return }
  59. guard let coordinator = transitionCoordinator,
  60. animated else {
  61. navBar.setBackgroundImage()
  62. navBar.clear()
  63. return
  64. }
  65. navBar.constructViewHierarchy()
  66. guard !coordinator.isInteractive else { return }
  67. coordinator.animate(alongsideTransition: { (transitionContext) in
  68. DispatchQueue.main.async {
  69. UIView.beginAnimations(nil, context: nil)
  70. UIView.setAnimationCurve(transitionContext.completionCurve)
  71. UIView.setAnimationDuration(transitionContext.transitionDuration)
  72. navBar.transitionAnimation()
  73. UIView.commitAnimations()
  74. }
  75. }, completion: { (transitionContext) in
  76. navBar.clear()
  77. })
  78. }
  79. }
  80. extension NavigationController: UIGestureRecognizerDelegate {
  81. public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
  82. if gestureRecognizer == interactivePopGestureRecognizer {
  83. return viewControllers.count > 1
  84. }
  85. return true
  86. }
  87. }