Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zwaldowski/d2ff9eeef945f643c6e0a58fba4343b8 to your computer and use it in GitHub Desktop.
Save zwaldowski/d2ff9eeef945f643c6e0a58fba4343b8 to your computer and use it in GitHub Desktop.
final class NavigationPopTransitionController: UIPercentDrivenInteractiveTransition {
let navigationController: UINavigationController
private lazy var interactivePopGestureRecognizer = UIScreenEdgePanGestureRecognizer(target: self, action: #selector(handle))
var ifInteractive: Self? {
interactivePopGestureRecognizer.state == .began ? self : nil
}
init(navigationController: UINavigationController) {
self.navigationController = navigationController
super.init()
interactivePopGestureRecognizer.edges = .left
interactivePopGestureRecognizer.delegate = self
navigationController.view.addGestureRecognizer(interactivePopGestureRecognizer)
}
}
private extension NavigationPopTransitionController {
@objc func handle(_ recognizer: UIScreenEdgePanGestureRecognizer) {
guard let view = recognizer.view else { return }
let translation = recognizer.translation(in: view)
let velocity = recognizer.velocity(in: view)
let width = view.bounds.width
let progress = translation.x / width
switch recognizer.state {
case .began:
navigationController.popViewController(animated: true)
case .changed:
update(min(progress, 0.999))
case .ended:
if progress >= 0.5 || velocity.x > 0 {
completionSpeed = duration * velocity.x / width
finish()
} else {
cancel()
}
case .cancelled:
cancel()
default:
break
}
}
}
extension NavigationPopTransitionController: UIGestureRecognizerDelegate {
func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
// Only allowed if no active transition.
return navigationController.transitionCoordinator == nil
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldBeRequiredToFailBy otherGestureRecognizer: UIGestureRecognizer) -> Bool {
// Don't muck up horizontal scrolling.
otherGestureRecognizer is UIPanGestureRecognizer && otherGestureRecognizer.view is UIScrollView
}
}
extension Foo: UINavigationControllerDelegate {
lazy var navigationPopTransition = NavigationPopTransitionController(...)
func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationController.Operation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
MyAwesomeAnimator(for: operation)
}
func navigationController(_ navigationController: UINavigationController, interactionControllerFor animationController: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? {
navigationPopTransition?.ifInteractive
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment