|
/* |
|
This class re-enables the interactivePopGestureRecognizer |
|
functionality that we lose when we implement our own back button handling. |
|
|
|
It disables the pop gesture in three scenarios: |
|
1) when the user is still on the root view controller |
|
2) when a push animation is in progress |
|
3) when the user swipes quickly multiple times and animations don't have time to be performed |
|
*/ |
|
|
|
import UIKit |
|
|
|
final class SwipeNavigationController: UINavigationController { |
|
|
|
// MARK: - Lifecycle |
|
|
|
override init(rootViewController: UIViewController) { |
|
super.init(rootViewController: rootViewController) |
|
} |
|
|
|
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { |
|
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) |
|
|
|
delegate = self |
|
} |
|
|
|
override func viewDidLoad() { |
|
super.viewDidLoad() |
|
|
|
// This needs to be in here, not in init |
|
interactivePopGestureRecognizer?.delegate = self |
|
} |
|
|
|
deinit { |
|
delegate = nil |
|
interactivePopGestureRecognizer?.delegate = nil |
|
} |
|
|
|
// MARK: - Overrides |
|
|
|
override func pushViewController(_ viewController: UIViewController, animated: Bool) { |
|
duringPushAnimation = true |
|
|
|
super.pushViewController(viewController, animated: animated) |
|
} |
|
|
|
// MARK: - Private Properties |
|
|
|
fileprivate var duringPushAnimation = false |
|
|
|
// MARK: - Unsupported Initializers |
|
|
|
required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } |
|
|
|
} |
|
|
|
// MARK: - UINavigationControllerDelegate |
|
|
|
extension SwipeNavigationController: UINavigationControllerDelegate { |
|
|
|
func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) { |
|
guard let swipeNavigationController = navigationController as? SwipeNavigationController else { return } |
|
|
|
swipeNavigationController.duringPushAnimation = false |
|
} |
|
|
|
} |
|
|
|
// MARK: - UIGestureRecognizerDelegate |
|
|
|
extension SwipeNavigationController: UIGestureRecognizerDelegate { |
|
|
|
func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool { |
|
guard gestureRecognizer == interactivePopGestureRecognizer else { |
|
return true // default value will disable the gesture |
|
} |
|
|
|
return viewControllers.count > 1 && duringPushAnimation == false |
|
} |
|
} |
add
delegate = self
to
override init(rootViewController: UIViewController)