如何在设置 leftBarButtonItem 后在 UINavigationController 中启用 back/left 滑动手势?
How to enable back/left swipe gesture in UINavigationController after setting leftBarButtonItem?
我从 here 得到了相反的问题。
在 iOS7
中默认,UINavigationController
堆栈的向后滑动手势可以弹出呈现的 ViewController
。现在我只是为所有 ViewControllers
.
统一了所有 self.navigationItem.leftBarButtonItem
样式
代码如下:
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithImage:LOADIMAGE(@"back_button") style:UIBarButtonItemStylePlain target:self action:@selector(popCurrentViewController)];
之后,navigationController.interactivePopGestureRecognizer
被禁用。如何在不删除自定义 leftBarButtonItem
的情况下启用弹出手势?
谢谢!
首先在 viewDidLoad 中设置委托:
self.navigationController.interactivePopGestureRecognizer.delegate = self;
然后在按下时禁用手势:
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
[super pushViewController:viewController animated:animated];
self.interactivePopGestureRecognizer.enabled = NO;
}
并在 viewDidDisappear 中启用:
self.navigationController.interactivePopGestureRecognizer.enabled = YES;
此外,将 UINavigationControllerDelegate
添加到您的视图控制器。
当我设置委托时它对我有用
self.navigationController.interactivePopGestureRecognizer.delegate = self;
然后实施
Swift
extension MyViewController:UIGestureRecognizerDelegate {
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldBeRequiredToFailBy otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
}
Objective-C
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
设置自定义后退按钮禁用滑动返回功能。
保留它的最好办法是继承 UINavigationViewController
并将其自身设置为 interactivePopGestureRecognizer
委托;然后你可以从 gestureRecognizerShouldBegin
return YES 允许向后滑动。
例如,这是在AHKNavigationController
中完成的
还有一个 Swift 版本:
对我有用 Swift 3:
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldBeRequiredToFailBy otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
并在 ViewDidLoad 中:
self.navigationController?.interactivePopGestureRecognizer?.delegate = self
self.navigationController?.interactivePopGestureRecognizer?.isEnabled = true
Swift 3:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.interactivePopGestureRecognizer?.delegate = self
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return (otherGestureRecognizer is UIScreenEdgePanGestureRecognizer)
}
这是在 iOS 10、Swift 3[= 中启用/禁用滑动弹出视图控制器的最佳方式23=]:
对于第一个屏幕[您想禁用滑动手势的地方]:
class SignUpViewController : UIViewController,UIGestureRecognizerDelegate {
//MARK: - View initializers
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
swipeToPop()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func swipeToPop() {
self.navigationController?.interactivePopGestureRecognizer?.isEnabled = true;
self.navigationController?.interactivePopGestureRecognizer?.delegate = self;
}
func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
if gestureRecognizer == self.navigationController?.interactivePopGestureRecognizer {
return false
}
return true
} }
对于中间屏幕[要启用滑动手势的位置]:
class FriendListViewController : UIViewController {
//MARK: - View initializers
override func viewDidLoad() {
super.viewDidLoad()
swipeToPop()
}
func swipeToPop() {
self.navigationController?.interactivePopGestureRecognizer?.isEnabled = true;
self.navigationController?.interactivePopGestureRecognizer?.delegate = nil;
} }
您需要处理两种情况:
- 当您将新视图推入堆栈时
- 当您显示根视图控制器时
如果你只需要一个基础 class 就可以使用,这里有一个 Swift 3 版本:
import UIKit
final class SwipeNavigationController: UINavigationController {
// MARK: - Lifecycle
override init(rootViewController: UIViewController) {
super.init(rootViewController: rootViewController)
delegate = self
}
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
delegate = self
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
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: - 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
}
// Disable pop gesture in two situations:
// 1) when the pop animation is in progress
// 2) when user swipes quickly a couple of times and animations don't have time to be performed
return viewControllers.count > 1 && duringPushAnimation == false
}
}
如果您最终需要在另一个 class 中充当 UINavigationControllerDelegate
,您可以编写委托转发器 similar to this answer。
改编自 Objective-C 中的源代码:https://github.com/fastred/AHKNavigationController
对于那些仍然有此问题的人,请尝试将两行分开,如下所示。
override func viewDidLoad() {
self.navigationController!.interactivePopGestureRecognizer!.delegate = self
...
override func viewWillAppear(_ animated: Bool) {
self.navigationController!.interactivePopGestureRecognizer!.isEnabled = true
...
显然,在我的应用中,
interactivePopGestureRecognizer!.isEnabled
由于某种原因在显示视图之前被重置为 false
。
回答,但有故事板支持。
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)
self.setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.setup()
}
private func setup() {
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
}
我不需要为它添加 gestureRecognizer 函数。我在 viewDidLoad:
添加以下代码块就足够了
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.interactivePopGestureRecognizer?.delegate = nil
self.navigationController?.interactivePopGestureRecognizer?.isEnabled = true
}
在Swift中可以执行以下代码
import UIKit
extension UINavigationController: UIGestureRecognizerDelegate {
open override func viewDidLoad() {
super.viewDidLoad()
interactivePopGestureRecognizer?.delegate = self
}
public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
return viewControllers.count > 1
}
}
以上代码有助于 swift 返回到之前的控制器,如 Facebook、Twitter。
如果您希望在您的应用程序中的任何地方都有这种行为,并且不想向个人添加任何东西 viewDidAppear
等,那么您应该创建一个子类
class QFNavigationController:UINavigationController, UIGestureRecognizerDelegate, UINavigationControllerDelegate{
override func viewDidLoad() {
super.viewDidLoad()
interactivePopGestureRecognizer?.delegate = self
delegate = self
}
override func pushViewController(_ viewController: UIViewController, animated: Bool) {
super.pushViewController(viewController, animated: animated)
interactivePopGestureRecognizer?.isEnabled = false
}
func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {
interactivePopGestureRecognizer?.isEnabled = true
}
// IMPORTANT: without this if you attempt swipe on
// first view controller you may be unable to push the next one
func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
return viewControllers.count > 1
}
}
现在,无论何时使用 QFNavigationController
,您都会获得所需的体验。
我们都在解决 some old bugs 可能尚未修复的问题,因为它是“设计使然”。我 运行 遇到冻结问题 @iwasrobbed 在尝试使 interactivePopGestureRecognizer
的委托无效时在其他地方描述过,这似乎应该有效。如果您想要使用 backBarButtonItem
重新考虑滑动行为,您可以 自定义。
我也 运行 进入 interactivePopGestureRecognizer
当 UINavigationBar
被隐藏时不工作。如果您担心隐藏导航栏,请在实施错误解决方法之前重新考虑您的设计。
大多数答案都与在代码上进行有关。但我会给你一个在故事板上工作的。是的!你没看错。
单击主 UINavigationController
并导航到它的 Identity Inspector
选项卡。
在 User Defined Runtime Attributes
下,将名为 interactivePopGestureRecognizer.enabled
的单个运行时 属性 设置为 true
。或者以图形方式,您必须启用复选框,如下图所示。
就是这样。你可以开始了。您的后退手势会一直有效。
Swift 5、viewDidLoad方法中只添加这两个:
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.interactivePopGestureRecognizer?.delegate = self
navigationController?.interactivePopGestureRecognizer?.isEnabled = true
}
我在启用和禁用滑动交互以弹出视图控制器时遇到问题。
我有一个基本导航控制器,我的应用程序流程就像推送 Splash VC、推送 Main VC,然后推送 Some VC 那样。
我想滑动以从 Some VC 返回到 Main VC。同时禁用滑动以防止从主 VC.
返回飞溅
经过以下尝试后对我有用。
- 在 Main VC 中写一个扩展来禁用滑动
extension MainViewController : UIGestureRecognizerDelegate{
func disableSwipeToPop() {
self.navigationController?.interactivePopGestureRecognizer?.isEnabled = true
self.navigationController?.interactivePopGestureRecognizer?.delegate = self
}
func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
if gestureRecognizer == self.navigationController?.interactivePopGestureRecognizer {
return false
}
return true
}
}
- 在 Main 的 viewDidAppear 上调用 disableSwipeToPop() 方法 VC
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.disableSwipeToPop()
}
- 在 Some VC 中写一个扩展,使滑动弹出 Some VC
extension SomeViewController{
func enableSwipeToPop() {
self.navigationController?.interactivePopGestureRecognizer?.isEnabled = true
self.navigationController?.interactivePopGestureRecognizer?.delegate = nil
}
}
- 在某些 VC
的 viewDidLoad 上调用 enableSwipeToPop() 方法
override func viewDidLoad() {
super.viewDidLoad()
self.enableSwipeToPop()
}
就是这样。此外,如果您尝试在 viewWillAppear 上禁用滑动,当用户停止滑动以取消操作时,您可能会失去再次滑动的能力。
我创建了以下 Swift 5+
UIViewController
扩展程序,以便在您需要的每个屏幕上更轻松地 add/remove 交互式弹出手势。
注:
在每个具有自定义后退按钮的屏幕上添加 enableInteractivePopGesture()
在导航控制器的根屏幕 viewDidAppear
上添加 disableInteractivePopGesture()
以防止向后滑动问题 此处提到的一些答案
同时在您不希望有后退按钮和向后滑动手势的推送屏幕上添加 disableInteractivePopGesture()
extension UIViewController: UIGestureRecognizerDelegate {
func disableInteractivePopGesture() {
navigationItem.hidesBackButton = true
navigationController?.interactivePopGestureRecognizer?.delegate = self
navigationController?.interactivePopGestureRecognizer?.isEnabled = false
}
func enableInteractivePopGesture() {
navigationController?.interactivePopGestureRecognizer?.delegate = self
navigationController?.interactivePopGestureRecognizer?.isEnabled = true
}
}
我从 here 得到了相反的问题。
在 iOS7
中默认,UINavigationController
堆栈的向后滑动手势可以弹出呈现的 ViewController
。现在我只是为所有 ViewControllers
.
self.navigationItem.leftBarButtonItem
样式
代码如下:
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithImage:LOADIMAGE(@"back_button") style:UIBarButtonItemStylePlain target:self action:@selector(popCurrentViewController)];
之后,navigationController.interactivePopGestureRecognizer
被禁用。如何在不删除自定义 leftBarButtonItem
的情况下启用弹出手势?
谢谢!
首先在 viewDidLoad 中设置委托:
self.navigationController.interactivePopGestureRecognizer.delegate = self;
然后在按下时禁用手势:
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
[super pushViewController:viewController animated:animated];
self.interactivePopGestureRecognizer.enabled = NO;
}
并在 viewDidDisappear 中启用:
self.navigationController.interactivePopGestureRecognizer.enabled = YES;
此外,将 UINavigationControllerDelegate
添加到您的视图控制器。
当我设置委托时它对我有用
self.navigationController.interactivePopGestureRecognizer.delegate = self;
然后实施
Swift
extension MyViewController:UIGestureRecognizerDelegate {
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldBeRequiredToFailBy otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
}
Objective-C
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
设置自定义后退按钮禁用滑动返回功能。
保留它的最好办法是继承 UINavigationViewController
并将其自身设置为 interactivePopGestureRecognizer
委托;然后你可以从 gestureRecognizerShouldBegin
return YES 允许向后滑动。
例如,这是在AHKNavigationController
中完成的还有一个 Swift 版本:
对我有用 Swift 3:
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldBeRequiredToFailBy otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
并在 ViewDidLoad 中:
self.navigationController?.interactivePopGestureRecognizer?.delegate = self
self.navigationController?.interactivePopGestureRecognizer?.isEnabled = true
Swift 3:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.interactivePopGestureRecognizer?.delegate = self
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return (otherGestureRecognizer is UIScreenEdgePanGestureRecognizer)
}
这是在 iOS 10、Swift 3[= 中启用/禁用滑动弹出视图控制器的最佳方式23=]:
对于第一个屏幕[您想禁用滑动手势的地方]:
class SignUpViewController : UIViewController,UIGestureRecognizerDelegate {
//MARK: - View initializers
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
swipeToPop()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func swipeToPop() {
self.navigationController?.interactivePopGestureRecognizer?.isEnabled = true;
self.navigationController?.interactivePopGestureRecognizer?.delegate = self;
}
func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
if gestureRecognizer == self.navigationController?.interactivePopGestureRecognizer {
return false
}
return true
} }
对于中间屏幕[要启用滑动手势的位置]:
class FriendListViewController : UIViewController {
//MARK: - View initializers
override func viewDidLoad() {
super.viewDidLoad()
swipeToPop()
}
func swipeToPop() {
self.navigationController?.interactivePopGestureRecognizer?.isEnabled = true;
self.navigationController?.interactivePopGestureRecognizer?.delegate = nil;
} }
您需要处理两种情况:
- 当您将新视图推入堆栈时
- 当您显示根视图控制器时
如果你只需要一个基础 class 就可以使用,这里有一个 Swift 3 版本:
import UIKit
final class SwipeNavigationController: UINavigationController {
// MARK: - Lifecycle
override init(rootViewController: UIViewController) {
super.init(rootViewController: rootViewController)
delegate = self
}
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
delegate = self
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
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: - 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
}
// Disable pop gesture in two situations:
// 1) when the pop animation is in progress
// 2) when user swipes quickly a couple of times and animations don't have time to be performed
return viewControllers.count > 1 && duringPushAnimation == false
}
}
如果您最终需要在另一个 class 中充当 UINavigationControllerDelegate
,您可以编写委托转发器 similar to this answer。
改编自 Objective-C 中的源代码:https://github.com/fastred/AHKNavigationController
对于那些仍然有此问题的人,请尝试将两行分开,如下所示。
override func viewDidLoad() {
self.navigationController!.interactivePopGestureRecognizer!.delegate = self
...
override func viewWillAppear(_ animated: Bool) {
self.navigationController!.interactivePopGestureRecognizer!.isEnabled = true
...
显然,在我的应用中,
interactivePopGestureRecognizer!.isEnabled
由于某种原因在显示视图之前被重置为 false
。
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)
self.setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.setup()
}
private func setup() {
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
}
我不需要为它添加 gestureRecognizer 函数。我在 viewDidLoad:
添加以下代码块就足够了override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.interactivePopGestureRecognizer?.delegate = nil
self.navigationController?.interactivePopGestureRecognizer?.isEnabled = true
}
在Swift中可以执行以下代码
import UIKit
extension UINavigationController: UIGestureRecognizerDelegate {
open override func viewDidLoad() {
super.viewDidLoad()
interactivePopGestureRecognizer?.delegate = self
}
public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
return viewControllers.count > 1
}
}
以上代码有助于 swift 返回到之前的控制器,如 Facebook、Twitter。
如果您希望在您的应用程序中的任何地方都有这种行为,并且不想向个人添加任何东西 viewDidAppear
等,那么您应该创建一个子类
class QFNavigationController:UINavigationController, UIGestureRecognizerDelegate, UINavigationControllerDelegate{
override func viewDidLoad() {
super.viewDidLoad()
interactivePopGestureRecognizer?.delegate = self
delegate = self
}
override func pushViewController(_ viewController: UIViewController, animated: Bool) {
super.pushViewController(viewController, animated: animated)
interactivePopGestureRecognizer?.isEnabled = false
}
func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {
interactivePopGestureRecognizer?.isEnabled = true
}
// IMPORTANT: without this if you attempt swipe on
// first view controller you may be unable to push the next one
func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
return viewControllers.count > 1
}
}
现在,无论何时使用 QFNavigationController
,您都会获得所需的体验。
我们都在解决 some old bugs 可能尚未修复的问题,因为它是“设计使然”。我 运行 遇到冻结问题 @iwasrobbed 在尝试使 interactivePopGestureRecognizer
的委托无效时在其他地方描述过,这似乎应该有效。如果您想要使用 backBarButtonItem
重新考虑滑动行为,您可以 自定义。
我也 运行 进入 interactivePopGestureRecognizer
当 UINavigationBar
被隐藏时不工作。如果您担心隐藏导航栏,请在实施错误解决方法之前重新考虑您的设计。
大多数答案都与在代码上进行有关。但我会给你一个在故事板上工作的。是的!你没看错。
单击主
UINavigationController
并导航到它的Identity Inspector
选项卡。在
User Defined Runtime Attributes
下,将名为interactivePopGestureRecognizer.enabled
的单个运行时 属性 设置为true
。或者以图形方式,您必须启用复选框,如下图所示。
就是这样。你可以开始了。您的后退手势会一直有效。
Swift 5、viewDidLoad方法中只添加这两个:
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.interactivePopGestureRecognizer?.delegate = self
navigationController?.interactivePopGestureRecognizer?.isEnabled = true
}
我在启用和禁用滑动交互以弹出视图控制器时遇到问题。
我有一个基本导航控制器,我的应用程序流程就像推送 Splash VC、推送 Main VC,然后推送 Some VC 那样。
我想滑动以从 Some VC 返回到 Main VC。同时禁用滑动以防止从主 VC.
返回飞溅经过以下尝试后对我有用。
- 在 Main VC 中写一个扩展来禁用滑动
extension MainViewController : UIGestureRecognizerDelegate{
func disableSwipeToPop() {
self.navigationController?.interactivePopGestureRecognizer?.isEnabled = true
self.navigationController?.interactivePopGestureRecognizer?.delegate = self
}
func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
if gestureRecognizer == self.navigationController?.interactivePopGestureRecognizer {
return false
}
return true
}
}
- 在 Main 的 viewDidAppear 上调用 disableSwipeToPop() 方法 VC
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.disableSwipeToPop()
}
- 在 Some VC 中写一个扩展,使滑动弹出 Some VC
extension SomeViewController{
func enableSwipeToPop() {
self.navigationController?.interactivePopGestureRecognizer?.isEnabled = true
self.navigationController?.interactivePopGestureRecognizer?.delegate = nil
}
}
- 在某些 VC 的 viewDidLoad 上调用 enableSwipeToPop() 方法
override func viewDidLoad() {
super.viewDidLoad()
self.enableSwipeToPop()
}
就是这样。此外,如果您尝试在 viewWillAppear 上禁用滑动,当用户停止滑动以取消操作时,您可能会失去再次滑动的能力。
我创建了以下 Swift 5+
UIViewController
扩展程序,以便在您需要的每个屏幕上更轻松地 add/remove 交互式弹出手势。
注:
在每个具有自定义后退按钮的屏幕上添加
enableInteractivePopGesture()
在导航控制器的根屏幕
viewDidAppear
上添加disableInteractivePopGesture()
以防止向后滑动问题 此处提到的一些答案同时在您不希望有后退按钮和向后滑动手势的推送屏幕上添加
disableInteractivePopGesture()
extension UIViewController: UIGestureRecognizerDelegate { func disableInteractivePopGesture() { navigationItem.hidesBackButton = true navigationController?.interactivePopGestureRecognizer?.delegate = self navigationController?.interactivePopGestureRecognizer?.isEnabled = false } func enableInteractivePopGesture() { navigationController?.interactivePopGestureRecognizer?.delegate = self navigationController?.interactivePopGestureRecognizer?.isEnabled = true } }