暂无描述

NavigationController.swift 4.2KB

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