|
//
// NavigationController.swift
// PaiaiUIKit
//
// Created by FFIB on 2019/4/23.
// Copyright © 2019 FFIB. All rights reserved.
//
import UIKit
public class NavigationController: UINavigationController {
override public init(rootViewController: UIViewController) {
super.init(navigationBarClass: NavigationBar.classForCoder(), toolbarClass: nil)
self.viewControllers = [rootViewController]
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override public init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}
override public func viewDidLoad() {
super.viewDidLoad()
delegate = self
interactivePopGestureRecognizer?.delegate = self
interactivePopGestureRecognizer?.isEnabled = true
interactivePopGestureRecognizer?.addTarget(self,
action: #selector(handlePop(gestureRecognizer:)))
}
@objc
private func handlePop(gestureRecognizer: UIPanGestureRecognizer) {
guard let navBar = navigationBar as? NavigationBar else { return }
if gestureRecognizer.state == .began { navBar.isPush = false }
guard navBar.needsInteractive else { return }
let percent = gestureRecognizer.translation(in: view).x / view.bounds.width
if gestureRecognizer.state == .began || gestureRecognizer.state == .changed {
navBar.transitionAnimationWithPercent(percent)
}
guard gestureRecognizer.state == .ended
|| gestureRecognizer.state == .cancelled
|| gestureRecognizer.state == .failed,
let coordinator = transitionCoordinator else { return }
navBar.bounce = percent < 0.5 ? .backward : .forward
let durationPercent = Double(percent < 0.5 ? coordinator.percentComplete : (1 - coordinator.percentComplete))
UIView.animate(withDuration: coordinator.transitionDuration * durationPercent,
delay: 0,
usingSpringWithDamping: 1,
initialSpringVelocity: coordinator.completionVelocity,
options: [],
animations: {
navBar.transitionAnimationWithPercent(1)
}, completion: { _ in
navBar.clear()
})
}
}
extension NavigationController: UINavigationControllerDelegate {
public func navigationController(_ navigationController: UINavigationController,
animationControllerFor operation: UINavigationController.Operation,
from fromVC: UIViewController,
to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
(navigationBar as? NavigationBar)?.isPush = operation == .push
return nil
}
public func navigationController(_ navigationController: UINavigationController,
willShow viewController: UIViewController,
animated: Bool) {
guard let navBar = navigationBar as? NavigationBar,
navBar.needsInteractive else { return }
guard let coordinator = transitionCoordinator,
animated else {
navBar.setBackgroundImage()
navBar.clear()
return
}
navBar.constructViewHierarchy()
guard !coordinator.isInteractive else { return }
coordinator.animate(alongsideTransition: { (transitionContext) in
DispatchQueue.main.async {
UIView.beginAnimations(nil, context: nil)
UIView.setAnimationCurve(transitionContext.completionCurve)
UIView.setAnimationDuration(transitionContext.transitionDuration)
navBar.transitionAnimation()
UIView.commitAnimations()
}
}, completion: { (_) in
navBar.clear()
})
}
}
extension NavigationController: UIGestureRecognizerDelegate {
public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
if gestureRecognizer == interactivePopGestureRecognizer {
return viewControllers.count > 1
}
return true
}
}
|