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
UINavigationController Interactive Pop Gesture Not Working?
提问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.delegate
property to nil
.
要解决这个问题,正如前面提到的其他人,您可以将该interactivePopGestureRecognizer.delegate
属性设置为nil
.
In Swift, this can easily be done across your entire application by adding an extension for :UINavigationController
like this
在斯威夫特, 这可以很容易地通过添加扩展为整个应用程序做:UINavigationController
这样的
extension UINavigationController {
override public func viewDidLoad() {
super.viewDidLoad()
interactivePopGestureRecognizer?.delegate = nil
}
}
Updated answer
更新答案
Seems like setting the delegate to nil
causes 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 gestureRecognizerShouldBegin
delegate method cannot be handled in an extension, subclassing UINavigationController
seems 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 nil
is 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
回答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
- Create a navigation controller
- 创建导航控制器
// I created a global variable, however not necessarily you will be doing this way
var nvc: UINavigationController!
- implement
UIGestureRecognizerDelegate
- 实施
UIGestureRecognizerDelegate
class AppDelegate: UIResponder, UIApplicationDelegate, UIGestureRecognizerDelegate {
- Instantiat
UINavigationController
in application didFinishLaunchingWithOptions function
UINavigationController
在应用程序中实例化didFinishLaunchingWithOptions 函数
nvc=UINavigationController()
// For interactive pop gesture
nvc.navigationBar.isHidden=true
nvc?.interactivePopGestureRecognizer?.delegate=self
- Extra step, add controller to navigation controller in application didFinishLaunchingWithOptions function
- 额外的步骤,在应用 didFinishLaunchingWithOptions 函数中将控制器添加到导航控制器
window=UIWindow()
window?.rootViewController=nvc
window?.makeKeyAndVisible()
// BaseViewController is sample controller i created with xib
nvc.pushViewController(BaseViewController(), animated: true)
- Implement gusture recognizer, add below code to AppDelegate.swift
- 实现姿态识别器,将以下代码添加到 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