ios UINavigationController 交互式流行手势不起作用?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18946302/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 01:32:16  来源:igfitidea点击:

UINavigationController Interactive Pop Gesture Not Working?

iosuinavigationcontrollerios7gesture

提问by Aaron Wojnowski

So I have a navigation controller in my built for iOS 7 app. The titleView is visible, as well as the back button and navigation bar its self. For some reason, the interactive pop gesture (swipe from the left edge) isn't working. Nothing happens. When I log the gesture, it is not nil. Is there anything special I have to do to enable this functionality? What could cause it not to work?

所以我在我为 iOS 7 应用程序构建的中有一个导航控制器。titleView 是可见的,以及后退按钮和导航栏本身。出于某种原因,交互式弹出手势(从左边缘滑动)不起作用。没发生什么事。当我记录手势时,它不是零。要启用此功能,我需要做什么特别的事情吗?什么可能导致它不起作用?

采纳答案by Aaron Wojnowski

Eh, looks like I just had to set the gesture delegate and implement the following:

呃,看起来我只需要设置手势委托并实现以下内容:

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {

    return YES;

}

回答by Eneko Alonso

I have found that when using custom back buttons, the interactive pop gesture stops working (my take is that Apple cannot foresee how your custom back button will behave, so they disable the gesture).

我发现当使用自定义后退按钮时,交互式弹出手势停止工作(我的看法是 Apple 无法预见您的自定义后退按钮的行为,因此他们禁用了该手势)。

To fix this, as other mentioned before, you can set the interactivePopGestureRecognizer.delegateproperty to nil.

要解决这个问题,正如前面提到的其他人,您可以将该interactivePopGestureRecognizer.delegate属性设置为nil.

In Swift, this can easily be done across your entire application by adding an extension for UINavigationControllerlike this:

在斯威夫特, 这可以很容易地通过添加扩展为整个应用程序做UINavigationController这样的

extension UINavigationController {

    override public func viewDidLoad() {
        super.viewDidLoad()
        interactivePopGestureRecognizer?.delegate = nil
    }

}

Updated answer

更新答案

Seems like setting the delegate to nilcauses the app UI to freeze in some scenarios (eg. when the user swipes left or right on the top view controller of the navigation stack).

似乎将委托设置为nil导致应用程序 UI 在某些情况下冻结(例如,当用户在导航堆栈的顶部视图控制器上向左或向右滑动时)。

Because gestureRecognizerShouldBegindelegate method cannot be handled in an extension, subclassing UINavigationControllerseems like the best solution:

因为gestureRecognizerShouldBegin委托方法不能在扩展中处理,子类化UINavigationController似乎是最好的解决方案:

class NavigationController: UINavigationController, UIGestureRecognizerDelegate {

    /// Custom back buttons disable the interactive pop animation
    /// To enable it back we set the recognizer to `self`
    override func viewDidLoad() {
        super.viewDidLoad()
        interactivePopGestureRecognizer?.delegate = self
    }

    func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer) -> Bool {
        return viewControllers.count > 1
    }

}

回答by cromandini

Look at this responseand comments. All you have to do is set your navigation controller's interactive pop gesture recognizer's delegate to nil:

看看这个回复和评论。您所要做的就是将导航控制器的交互式流行手势识别器的委托设置为nil

self.navigationController.interactivePopGestureRecognizer.delegate = nil;

Setting it to a casted self to id<UIGestureRecognizerDelegate>also works because all methods in the protocol are optional, but I think setting the delegate to nilis more appropriate in this case.

将其设置为强制转换的 selfid<UIGestureRecognizerDelegate>也有效,因为协议中的所有方法都是可选的,但我认为nil在这种情况下将委托设置为更合适。

回答by lojals

You can put this line in the viewDidLoadmethod.

您可以将此行放在viewDidLoad方法中。

self.navigationController.interactivePopGestureRecognizer.delegate = (id<UIGestureRecognizerDelegate>)self;

回答by Kukiwon

My answer is based on Eneko's answer but uses only an extension on UINavigationController and works in Swift 5:

我的答案基于 Eneko 的答案,但仅使用 UINavigationController 上的扩展并在 Swift 5 中工作:

extension UINavigationController: UIGestureRecognizerDelegate {

    override open func viewDidLoad() {
        super.viewDidLoad()
        interactivePopGestureRecognizer?.delegate = self
    }

    public func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        return viewControllers.count > 1
    }
}

回答by Vicky Dhas

The more worked out answer was both Aaron and lojals

更有效的答案是 Aaron 和 lojals

First Customise the Navigation controller and then put this code in the class

先自定义导航控制器,然后把这段代码放到类中

In ViewDidload put this line:

在 ViewDidload 中放置这一行:

self.navigationController.interactivePopGestureRecognizer.delegate = (id<UIGestureRecognizerDelegate>)self;

And in class write this function

在课堂上写这个函数

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { return YES;}

回答by Doci

Maybe someone may find this helpful.

也许有人会觉得这很有帮助。

If you want to hide the navigation bar but use normal swipe gestures to go back and other navigation controller features, you should use: (navigationBar)

如果你想隐藏导航栏但使用普通的滑动手势返回和其他导航控制器功能,你应该使用:(navigationBar

self.navigationController?.navigationBar.isHidden = true

If you want to disable navigation bar (hide navigation bar, disable swipe for back) but want to push viewcontroller you should use: (isNavigationBarHidden)

如果您想禁用导航栏(隐藏导航栏,禁用向后滑动)但想推动视图控制器,您应该使用:(isNavigationBarHidden

self.navigationController?.isNavigationBarHidden = true

Update 7-DEC-2018:

2018 年 12 月 7 日更新:

Recommended way:

推荐方式:

In case that your first controller use hidden navigation bar, but next childs use navigation bar, when you come back to base view controller you will see a black bar in transition in place of navigation bar. This will be fixed very easy if you use in first viewcontroller(father):

如果您的第一个控制器使用隐藏导航栏,但下一个孩子使用导航栏,当您返回基本视图控制器时,您将看到一个黑色栏代替导航栏。如果您在第一个视图控制器(父亲)中使用,这将很容易解决:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    self.navigationController?.setNavigationBarHidden(true, animated: animated)
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    self.navigationController?.setNavigationBarHidden(false, animated: animated)
}

回答by Doci

In Swift 4, I have a UITableView inside my view controller, I solved this issue with:

在 Swift 4 中,我的视图控制器中有一个 UITableView,我用以下方法解决了这个问题:

override func viewDidLoad() {
    super.viewDidLoad()
    self.navigationController?.interactivePopGestureRecognizer?.delegate=nil
}

回答by COVID19

If you feel you have tried all solutions and stretching your head then you're at the right place.

如果你觉得你已经尝试了所有的解决方案并伸展你的头,那么你来对地方了。

Goto simulator > Window > Enable Show Device Bezels

enter image description here

在此处输入图片说明

Now tried to simulate swipe to back gesture.

现在尝试模拟向后滑动手势。

回答by Rakesh Yembaram

Generically add interactive pop gesture to the whole app.

一般为整个应用程序添加交互式弹出手势。

XCODE: 9.0, Swift: 4.0

XCODE:9.0,斯威夫特:4.0

Preferably create UINavigationController in AppDelegate.swift

最好在 AppDelegate.swift 中创建 UINavigationController

  1. Create a navigation controller
  1. 创建导航控制器
// I created a global variable, however not necessarily you will be doing this way
var nvc: UINavigationController!
  1. implement UIGestureRecognizerDelegate
  1. 实施 UIGestureRecognizerDelegate
class AppDelegate: UIResponder, UIApplicationDelegate, UIGestureRecognizerDelegate {
  1. Instantiat UINavigationControllerin application didFinishLaunchingWithOptions function
  1. UINavigationController在应用程序中实例化didFinishLaunchingWithOptions 函数
nvc=UINavigationController()

// For interactive pop gesture
nvc.navigationBar.isHidden=true
nvc?.interactivePopGestureRecognizer?.delegate=self
  1. Extra step, add controller to navigation controller in application didFinishLaunchingWithOptions function
  1. 额外的步骤,在应用 didFinishLaunchingWithOptions 函数中将控制器添加到导航控制器
window=UIWindow()
window?.rootViewController=nvc
window?.makeKeyAndVisible()

// BaseViewController is sample controller i created with xib
nvc.pushViewController(BaseViewController(), animated: true)
  1. Implement gusture recognizer, add below code to AppDelegate.swift
  1. 实现姿态识别器,将以下代码添加到 AppDelegate.swift
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRequireFailureOf otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return true
    }



Note: See other post in this section for the difference between



注意:请参阅本节中的其他帖子以了解两者之间的区别

self.navigationController?.navigationBar.isHidden=true

And

self.navigationController?.isNavigationBarHidden = true