23

在我的应用程序中,我有不同的控制器。当我将控制器 1 推到导航控制器并向后滑动时,一切正常。但是,如果我推导航控制器 1,然后进入控制器 1 推控制器 2 并尝试向后滑动,我会得到一个冻结的应用程序。如果通过后退按钮返回一切正常。

我怎样才能发现问题?

4

9 回答 9

38

使用滑动弹出手势时,我遇到了与冻结界面类似的问题。就我而言,问题出在 controller1.viewDidAppear 我正在禁用滑动手势:self.navigationController.interactivePopGestureRecognizer.enabled = NO。因此,当用户开始从 contorller2 向后滑动时,controller1.viewDidAppear 被触发并且手势被禁用,就在它工作期间。

我通过self.navigationController.interactivePopGestureRecognizer.delegate = self在 controller1 中设置并实现来解决这个问题gestureRecognizerShouldBegin:,而不是禁用手势识别器:

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
    if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)] &&
            gestureRecognizer == self.navigationController.interactivePopGestureRecognizer) {
        return NO;
    }
    return YES;
}
于 2014-01-29T07:20:15.317 回答
19

我的解决方案是向导航控制器添加一个委托。然后仅在根视图控制器中禁用弹出手势识别器。YMMV。

#pragma mark - UINavigationControllerDelegate

- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    BOOL isRootVC = viewController == navigationController.viewControllers.firstObject;
    navigationController.interactivePopGestureRecognizer.enabled = !isRootVC;
}
于 2015-01-21T05:06:17.677 回答
5

我在第一个控制器上滑动然后点击 tableViewCell 时遇到问题,我认为从边缘强制触摸滑动是在切换应用程序之前注册滑动,有时 UI 卡住,有时当我向后滑动时它开始进入目标控制器。我解决了这个扩展的问题,它对我有用,而且是简单的解决方案。斯威夫特 4.2

extension UINavigationController:UINavigationControllerDelegate {

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

    public func navigationController(_ navigationController: UINavigationController, didShow viewController: UIViewController, animated: Bool) {
        if responds(to: #selector(getter: self.interactivePopGestureRecognizer)) {
            if viewControllers.count > 1 {
                interactivePopGestureRecognizer?.isEnabled = true
            } else {
                interactivePopGestureRecognizer?.isEnabled = false
            }
        }
    }
}
于 2019-03-29T19:56:22.717 回答
3

斯威夫特 4:

设置委托,

self.navigationController?.interactivePopGestureRecognizer?.delegate = self

实现委托方法,

extension YourVC: UIGestureRecognizerDelegate{
    func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
        if gestureRecognizer == self.navigationController?.interactivePopGestureRecognizer && conditionToDisableTheGesture {
            return false
        }else{
            return true
        }
    }

}
于 2019-02-26T12:33:39.053 回答
0

我有同样的问题,我找到了下面的解决方案。在控制器下面添加

#import <UIKit/UIKit.h>
@interface CBNavigationController : UINavigationController     <UIGestureRecognizerDelegate,UINavigationControllerDelegate>
@end

#import "CBNavigationController.h"
@interface CBNavigationController ()
@end
@implementation CBNavigationController
- (void)viewDidLoad
{
NSLog(@"%s",__FUNCTION__);
__weak CBNavigationController *weakSelf = self;

if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)])
{
    self.interactivePopGestureRecognizer.delegate = weakSelf;
    self.delegate = weakSelf;
}
}

- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
NSLog(@"%s",__FUNCTION__);

if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)])
    self.interactivePopGestureRecognizer.enabled = NO;

[super pushViewController:viewController animated:animated];
}

#pragma mark UINavigationControllerDelegate
- (void)navigationController:(UINavigationController *)navigationController
   didShowViewController:(UIViewController *)viewController
                animated:(BOOL)animate
{
NSLog(@"%s",__FUNCTION__);

// Enable the gesture again once the new controller is shown

if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)])
    self.interactivePopGestureRecognizer.enabled = YES;
}
@end

可以参考以下链接

http://keighl.com/post/ios7-interactive-pop-gesture-custom-back-button/

于 2014-02-26T05:18:18.377 回答
0

我的解决方案是在和self.navigationController.interactivePopGestureRecognizer.delegate之间交换selfImplementDelegateSystemDelegate

- (void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    [_tableView reloadData];
    _oldReturnDelegate = self.navigationController.interactivePopGestureRecognizer.delegate;
    self.navigationController.interactivePopGestureRecognizer.delegate = self;
}

- (void)viewWillDisappear:(BOOL)animated
{
    self.navigationController.interactivePopGestureRecognizer.delegate = _oldReturnDelegate;
    [super viewWillDisappear:animated];
}
于 2016-06-07T07:01:25.190 回答
0

我建议你试试这个。这对我来说非常有效。您仍然可以享受交互式滑动。

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
  if ([self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)] &&
      gestureRecognizer == self.navigationController.interactivePopGestureRecognizer) {
    if(self.navigationController.viewControllers.count<=1)
    {
      return NO;
    }
  }
  return YES;
}
于 2016-10-25T08:52:05.587 回答
0

斯威夫特 4

将此代码添加到根导航控制器

func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
    return self == self.navigationController?.topViewController ? false : true
}

添加 UIGestureRecognizerDelegate 协议

self.navigationController?.interactivePopGestureRecognizer?.delegate = self
self.navigationController?.interactivePopGestureRecognizer?.isEnabled = true
于 2019-01-11T11:55:39.433 回答
-2

我通过UINavigationController interactivePopGestureRecognizer 在 iOS7 中工作异常解决了我的问题并self.navigationController.interactivePopGestureRecognizer.delegate = self; 在每个 视图控制器上设置- (void)viewWillAppear:(BOOL)animated

于 2014-08-07T07:11:57.417 回答