From f0658f77f8289fe68bdba49fa71586d21ece09f7 Mon Sep 17 00:00:00 2001 From: CMK Date: Sat, 7 May 2022 11:43:37 +0800 Subject: [PATCH] feat: add navigation pan pop gesture. resolve #407 #419 --- ...veStatusBarStyleNavigationController.swift | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/Mastodon/Scene/Share/NavigationController/AdaptiveStatusBarStyleNavigationController.swift b/Mastodon/Scene/Share/NavigationController/AdaptiveStatusBarStyleNavigationController.swift index aac23285b..f4ad467da 100644 --- a/Mastodon/Scene/Share/NavigationController/AdaptiveStatusBarStyleNavigationController.swift +++ b/Mastodon/Scene/Share/NavigationController/AdaptiveStatusBarStyleNavigationController.swift @@ -10,7 +10,41 @@ import UIKit // Make status bar style adaptive for child view controller // SeeAlso: `modalPresentationCapturesStatusBarAppearance` class AdaptiveStatusBarStyleNavigationController: UINavigationController { + + private lazy var fullWidthBackGestureRecognizer = UIPanGestureRecognizer() + override var childForStatusBarStyle: UIViewController? { visibleViewController } } + +// ref: https://stackoverflow.com/a/60598558/3797903 +extension AdaptiveStatusBarStyleNavigationController { + + override func viewDidLoad() { + super.viewDidLoad() + setupFullWidthBackGesture() + } + + private func setupFullWidthBackGesture() { + // The trick here is to wire up our full-width `fullWidthBackGestureRecognizer` to execute the same handler as + // the system `interactivePopGestureRecognizer`. That's done by assigning the same "targets" (effectively + // object and selector) of the system one to our gesture recognizer. + guard let interactivePopGestureRecognizer = interactivePopGestureRecognizer, + let targets = interactivePopGestureRecognizer.value(forKey: "targets") + else { return } + + fullWidthBackGestureRecognizer.setValue(targets, forKey: "targets") + fullWidthBackGestureRecognizer.delegate = self + view.addGestureRecognizer(fullWidthBackGestureRecognizer) + } +} + +// MARK: - UIGestureRecognizerDelegate +extension AdaptiveStatusBarStyleNavigationController: UIGestureRecognizerDelegate { + func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool { + let isSystemSwipeToBackEnabled = interactivePopGestureRecognizer?.isEnabled == true + let isThereStackedViewControllers = viewControllers.count > 1 + return isSystemSwipeToBackEnabled && isThereStackedViewControllers + } +}