ChatGPT解决这个技术问题 Extra ChatGPT

在 Swift 中禁用向后滑动手势

在这里环顾了一段时间,但似乎找不到有效的解决方案。

我正在尝试在 Swift 中禁用滑动以返回上一个视图手势。

我尝试了多种解决方案,包括:

self.navigationController?.interactivePopGestureRecognizer.enabled = false

self.navigationController.interactivePopGestureRecognizer.delegate = self

func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer!) -> Bool {
    return false
}

有没有一种新的方法可以做到这一点或其他一些有效的方法?

当用户没有完全滑动时会导致问题,并干扰我们正在使用的 UI 的性质(在音轨中寻找时间)
好吧,我不想打断你的问题,但我建议你 (1) 解决不完全滑动的问题和 (2) 缩进你的音轨搜索 UI,这样它就不会那么靠近边缘。这是预期的 UX,对于 iPhone 6 Plus 和 iPad 用户来说尤其重要,因为它们很难进入导航栏。
无论如何,您的代码应该禁用手势识别器。它适用于旧版本的 iOS 吗?
关于 iPhone 6 的好点 - 也许我会考虑修改 dealloc 方法 - 但我仍然会留下这个问题,因为我仍然感兴趣
我至少在 iOS 8 上进行测试

C
CodeBender

以下是禁用和重新启用向后滑动的简单方法。

Swift 3.x 及更高版本

在 viewDidLoad/willAppear/didAppear 方法中添加:

navigationController?.interactivePopGestureRecognizer?.isEnabled = false

请记住,如果您使用 viewDidLoad 执行此操作,那么下次打开视图时,可能不会设置它,具体取决于它是否保留在您的堆栈中。

除非您希望它保持关闭,否则您需要在通过 willMove(toParentViewController:)willDisappear 关闭视图时重新打开它。您的 navigationControllerviewDidDisappear 将为零,所以为时已晚。

navigationController?.interactivePopGestureRecognizer?.isEnabled = true

关于 SplitViewControllers 的特别说明:

正如 CompC 在评论中指出的那样,您需要调用第二个导航控制器以将其应用于详细视图,如下所示:

navigationController?.navigationController?.interactivePopGe‌​stureRecognizer?.isE‌​nabled = false

Swift 2.2 和 Objective-C

Swift 2.x 及以下版本:

navigationController?.interactivePopGestureRecognizer?.enabled

目标-C:

self.navigationController.interactivePopGestureRecognizer.enabled

我在让它工作时遇到了一些麻烦,直到我意识到由于我试图禁用它的视图控制器位于拆分视图控制器的细节端,它在技术上位于一个单独的导航控制器中(即使,当折叠,看起来它在同一个控制器中)。为了解决这个问题,我必须这样做:navigationController?.navigationController?.interactivePopGestureRecognizer?.isEnabled = false
@CompC 感谢您的更新,从未有过这种情况,很高兴知道。
在 didAppear 中禁用它就足够了,然后在 willDisappear 中重新启用它。特别是在 didDisappear 上重新启用它是没有用的,因为 navigationController 属性已经为零。
谢谢,这应该是正确的答案
@iajmeri43 是的,创建 UINavigationController 的子类,然后在其 viewDidLoad 中设置属性。只要应用程序中您想要的所有视图都使用导航控制器,它就可以工作。
N
Nikolay Khramchenko

您可以禁用它,但不建议这样做,因为大多数 iOS 用户通过滑动返回而不是按返回按钮。如果你想禁用它,使用 modal segue 而不是推送 segue 会更合理,因为它不是那么大的传输。如果你真的想摆脱滑动返回功能,我会禁用返回按钮并在屏幕右上角有一个完成按钮。

self.navigationController?.navigationItem.backBarButtonItem?.isEnabled = false;

H
Hari Kunwar

我可以通过在gestureRecognizerShouldBegin中返回false来做到这一点

class ViewController2: UIViewController, UIGestureRecognizerDelegate {
...
override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.
    self.navigationController?.interactivePopGestureRecognizer.delegate = self
}

func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer) -> Bool {
    return false
}

注意 OP 代码中的 UIGestureRecognizer! 与此处的 UIGestureRecognizer
它的工作谢谢@Hari Kunwar
B
Behnam Rakhshani

在将视图控制器推送到导航控制器之前添加此行

self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false

R
RowanPD

Hari 或 Stefan 的回答都没有错,但这更简洁。只需将其放入 viewDidLoad 即可。

if navigationController!.respondsToSelector(Selector("interactivePopGestureRecognizer")) {
    navigationController!.view.removeGestureRecognizer(navigationController!.interactivePopGestureRecognizer)
}

编辑:

一个小警告是,如果导航控制器被另一个视图打开并且导航控制器关闭,那么您将收到 EXC_BAD_ACCESS 错误。要修复它,您必须保存原始 UIGestureRecognizer 并在退出视图时将其放回原处。

宣布:

private var popGesture: UIGestureRecognizer?

在移除手势之前:

popGesture = navigationController!.interactivePopGestureRecognizer

然后在关闭视图时:

If popGesture != nil {
    navigationController!.view.addGestureRecognizer(popGesture!)
}

D
David Seek

RowanPD 对 Swift 4 的逻辑

private var popGesture: UIGestureRecognizer?

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    if navigationController!.responds(to: #selector(getter: UINavigationController.interactivePopGestureRecognizer)) {
        self.popGesture = navigationController!.interactivePopGestureRecognizer
        self.navigationController!.view.removeGestureRecognizer(navigationController!.interactivePopGestureRecognizer!)
    }

}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)

    if let gesture = self.popGesture {
        self.navigationController!.view.addGestureRecognizer(gesture)
    }

}

I
Iskeraet

代替

self.navigationController.pushViewController(VC, animated: Bool)

称呼

self.navigationController.setViewContollers([VC], animated: Bool)

setViewControllers 替换堆栈上的所有 VC,而不是在顶部添加一个新控制器。这意味着新设置的 VC 是根 VC,用户无法返回。

当您只想禁用单个 VC 上的滑动并为其他 VC 保留滑动到背面时,这是最有效的。

如果您希望用户能够返回,而不是通过滑动,请不要使用此方法,因为它会禁用所有返回(因为没有 VC 可以返回)。


伟大的!谢谢!
r
rfornal

对于目标-c

-(void)viewWillAppear:(BOOL)animated{
  [super viewWillAppear:true];

  self.navigationController.interactivePopGestureRecognizer.enabled = NO;

}

b
blwinters

我通常会确保在尽可能多的地方启用向后滑动,甚至添加自定义手势识别器以将其添加到模态屏幕。但是,对于我的应用程序中的身份验证和下载过程,我使用模态导航控制器开始该过程,然后为每个下一步推送视图。但是,一旦完成,我想阻止他们备份到身份验证屏幕。

对于这种情况,我一直在使用:

navigationController?.interactivePopGestureRecognizer?.isEnabled = false
navigationItem.hidesBackButton = true

在最终屏幕上的 viewWillAppear() 中。如果您正在推送另一个视图并在那里需要它们,您可以在 viewWillDisappear() 中撤消这些操作。


L
Li Jin

如果您尝试了所有方法后它仍然不起作用,那么这是您错过的东西。

将 navigationController?.interactivePopGestureRecognizer?.isEnabled = false 添加到您的 viewWillAppear(animated:) 方法中。如果它不起作用,请从视图控制器中删除导航委托。再次检查您的视图控制器是否正在确认 UINavigationControllerDelegate、UIGestureRecognizerDelegate 协议。如果是这样,只需将其删除。


K
KaMaHe

来晚了一点。在我的情况下,self.navigationController?.navigationItem.backBarButtonItem?.isEnabled = false; 不起作用。所以我这样做:您可以呈现视图控制器而不是推送视图控制器。这样,向后滑动手势将不适用于视图控制器。

navigationController?.present(vc, animated: true)

您可以对自定义后退按钮使用关闭

self.dismiss(animated: true)

注意:您可以在呈现之前设置 VC 模态呈现样式,以确保它是全屏的。

vc.modalPresentationStyle = .fullScreen

希望这有帮助。


S
Spydy

如果需要在某些屏幕上显示侧边菜单,则在此特定视图上添加 AddScreenEdgePanGesture 而不是 navigationController 视图

代替它

SideMenuManager.default.menuAddScreenEdgePanGesturesToPresent(toView: self.navigationController?.view)

有了这个

SideMenuManager.default.menuAddScreenEdgePanGesturesToPresent(toView: self.view)

S
Sergey Koshelenko

如果您不关心系统后退按钮的外观(例如,如果您使用自定义后退按钮或导航栏完全隐藏),它可能会帮助您:

navigationItem.hidesBackButton = true

它隐藏后退按钮并禁用向后滑动手势。


G
Geri Borbás

只有完全删除手势识别器对我有用(来自呈现视图控制器)。

if let navigationController = parent.navigationController,
   let interactivePopGestureRecognizer = navigationController.interactivePopGestureRecognizer {
    navigationController.view.removeGestureRecognizer(interactivePopGestureRecognizer)
}

M
Muhammad Ahmad

如果您不想回来,请不要使用它,或者设置新的 rootViewController。

self.navigationController.pushViewController(VC, animated: Bool)

用这个

self.navigationController.setViewContollers([VC], animated: Bool)

setViewControllers 删除堆栈上的所有视图控制器,然后用户无法返回。它将禁用所有背部