Answers:
我找到了解决方案:
目标C:
if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
self.navigationController.interactivePopGestureRecognizer.enabled = NO;
}
迅捷3+:
self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false
enable / disable
在viewDidAppear:
/上识别viewDidDisappear
。或者,您可以UIGestureRecognizerDelegate
使用更复杂的逻辑来实现协议并将其设置为recognizer.delegate
属性。
self.navigationController.interactivePopGestureRecognizer.enabled
属性不会在以下视图的方法的工作:viewDidLoad
,viewWillAppear
,viewDidAppear
,viewDidDisappear
,但在方法作品viewWillDisappear
。在iOS7上,它可用于上述所有方法。因此,当在viewController上工作时,尝试在任何其他方法中使用它,当我单击视图内的某些按钮时,我确认它在iOS8上适用。
我发现将手势设置为“禁用”并不总是有效。它确实有效,但是对我来说,只有在我使用了手势之后才起作用。第二次它不会触发回退。
对我来说,解决的方法是委派该手势并实现shouldbegin方法以返回NO:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
// Disable iOS 7 back gesture
if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
self.navigationController.interactivePopGestureRecognizer.enabled = NO;
self.navigationController.interactivePopGestureRecognizer.delegate = self;
}
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
// Enable iOS 7 back gesture
if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
self.navigationController.interactivePopGestureRecognizer.enabled = YES;
self.navigationController.interactivePopGestureRecognizer.delegate = nil;
}
}
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
return NO;
}
viewWillAppear
在当前视图后面的视图上调用@AhsanEbrahim 。由于当前视图仍处于活动状态,因此这可能会导致代码逻辑混乱。可能是导致崩溃的原因。
enabled
需要是/否行?您NO
从回来gestureRecognizerShouldBegin
,还不够吗?
只需从NavigationController中删除手势识别器即可。在iOS 8中工作。
if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)])
[self.navigationController.view removeGestureRecognizer:self.navigationController.interactivePopGestureRecognizer];
[self.navigationController.view addGestureRecognizer:self.navigationController.interactivePopGestureRecognizer]
某个地方进行。
从iOS 8开始,已接受的答案不再有效。我需要停止滑动以消除我的主游戏屏幕上的手势,因此实现了以下目的:
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
self.navigationController.interactivePopGestureRecognizer.delegate = self;
}
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) {
self.navigationController.interactivePopGestureRecognizer.delegate = nil;
}
}
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
return NO;
}
我对Twan的答案做了一些改进,因为:
nil
当您返回到根视图控制器并在浏览其他位置之前进行滑动手势时,将委托设置为导致挂起问题。以下示例假定使用iOS 7:
{
id savedGestureRecognizerDelegate;
}
- (void)viewWillAppear:(BOOL)animated
{
savedGestureRecognizerDelegate = self.navigationController.interactivePopGestureRecognizer.delegate;
self.navigationController.interactivePopGestureRecognizer.delegate = self;
}
- (void)viewWillDisappear:(BOOL)animated
{
self.navigationController.interactivePopGestureRecognizer.delegate = savedGestureRecognizerDelegate;
}
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
if (gestureRecognizer == self.navigationController.interactivePopGestureRecognizer) {
return NO;
}
// add whatever logic you would otherwise have
return YES;
}
请在root vc中设置:
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:YES];
self.navigationController.interactivePopGestureRecognizer.enabled = NO;
}
-(void)viewDidDisappear:(BOOL)animated{
[super viewDidDisappear:YES];
self.navigationController.interactivePopGestureRecognizer.enabled = YES;
}
如果要管理特定导航控制器的向后滑动功能,请考虑使用SwipeBack。
有了这个,你可以设置 navigationController.swipeBackEnabled = NO
。
例如:
#import <SwipeBack/SwipeBack.h>
- (void)viewWillAppear:(BOOL)animated
{
navigationController.swipeBackEnabled = NO;
}
可以通过CocoaPods安装。
pod 'SwipeBack', '~> 1.0'
对于缺乏解释我深表歉意。
self.navigationController.swipeBackEnabled = NO
我也很确定这只会禁用您的系统手势图书馆的向后滑动手势,但系统的手势仍将启用。
我的方法 一个手势识别器将它们全部统治:
class DisabledGestureViewController: UIViewController: UIGestureRecognizerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
navigationController!.interactivePopGestureRecognizer!.delegate = self
}
func gestureRecognizerShouldBegin(gestureRecognizer: UIGestureRecognizer) -> Bool {
// Prevent going back to the previous view
return !(navigationController!.topViewController is DisabledGestureViewController)
}
}
重要提示:请勿在导航堆栈中的任何位置重置委托: navigationController!.interactivePopGestureRecognizer!.delegate = nil
所有这些解决方案都以他们不推荐的方式操纵苹果的手势识别器。一位朋友告诉我,有一个更好的解决方案:
[navigationController.interactivePopGestureRecognizer requireGestureRecognizerToFail: myPanGestureRecognizer];
其中myPanGestureRecognizer是用于例如显示菜单的手势识别器。这样一来,当您按下新的导航控制器时,Apple的手势识别器就不会再被打开,并且您不必依靠hacky的延迟,如果您的手机进入睡眠状态或负载过重,延迟可能会过早触发。
将此留在这里是因为我知道下次需要它时我将不记得了,然后在这里我将提供解决问题的方法。
给出的答案都没有帮助我解决问题。在这里发布我的答案;可能对某人有帮助
private var popGesture: UIGestureRecognizer?
在视图控制器中声明为全局变量。然后在viewDidAppear和viewWillDisappear方法中实现代码
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
if self.navigationController!.respondsToSelector(Selector("interactivePopGestureRecognizer")) {
self.popGesture = navigationController!.interactivePopGestureRecognizer
self.navigationController!.view.removeGestureRecognizer(navigationController!.interactivePopGestureRecognizer!)
}
}
override func viewWillDisappear(animated: Bool) {
super.viewWillDisappear(animated)
if self.popGesture != nil {
navigationController!.view.addGestureRecognizer(self.popGesture!)
}
}
这将在iOS v8.x及更高版本中禁用向后滑动
interactivePopGestureRecognizer.delegate
。
if( .. respondsToSelector ..
。下一行将popGesture设置为识别器,或设置为nil。然后使用其值:if (self.popGesture != nil) self.navigationController .. removeGestureRecognizer( self.popGesture )
。
这适用于viewDidLoad:
iOS 8:
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
self.navigationController.interactivePopGestureRecognizer.enabled = false;
});
好的帮助可以解决很多问题 dispatch_after
。
尽管请注意,此解决方案可能不安全,但请使用您自己的推理。
对于iOS 8.1,延迟时间应为0.5秒
在iOS 9.3上,不再需要延迟,只需将其放在您的viewDidLoad
:(
如果在iOS 9.0-9.3上可以使用,则为待定)
navigationController?.interactivePopGestureRecognizer?.enabled = false
viewDidLoad
加延迟是一种冒险的编程习惯。开始要养成一个坏习惯。如果用户在您的延迟呼叫开始之前开始滑动,该怎么办?没有安全时间可以保证足够长但又不能太长。因此,其他答案早于您的发布就建议将代码放入中viewDidAppear
。这样可以确保一切都已安装。不要发明任意的延迟;按预期使用Apple的通话顺序。
对于Swift 4,此方法有效:
class MyViewController: UIViewController, UIGestureRecognizerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.interactivePopGestureRecognizer?.gesture.delegate = self
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
self.navigationController?.interactivePopGestureRecognizer?.gesture.isEnabled = false
}
}
对于大多数视图控制器而言,它对我都有效。
self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false
对于某些视图控制器(如UIPageViewController),它不起作用。在UIPageViewController的pagecontentviewcontroller上,以下代码对我有用。
override func viewDidLoad() {
self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false
self.navigationController?.interactivePopGestureRecognizer?.delegate = self
}
override func viewWillDisappear(_ animated: Bool) {
self.navigationController?.interactivePopGestureRecognizer?.isEnabled = false
self.navigationController?.interactivePopGestureRecognizer?.delegate = nil
}
在UIGestureRecognizerDelegate上,
func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
if gestureRecognizer == self.navigationController?.interactivePopGestureRecognizer {
return false
}
return true
}