带有自定义后退按钮的滑动手势将冻结根视图控制器



我的应用程序中到处都有自定义的后退按钮,看起来导航控制器不喜欢它。

因此,我希望 iOS7 滑动返回手势与我的自定义后退按钮一起使用。搜索并尝试了不同的方法,但似乎没有一种是有希望的。我能得到的最接近的是 http://keighl.com/post/ios7-interactive-pop-gesture-custom-back-button/。但是,现在当我继续推动和弹出导航堆栈时,一段时间后堆栈中的 rootViewController 停止响应任何触摸。

有什么建议吗?

子类化UINavigationController,就像keighl建议的那样,是imo的正确方法。但是他缺少对根视图控制器的检查,以避免在根视图上执行手势时冻结。这是带有附加检查的修改版本:

CBNavigationController.h:

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

CBNavigationController.m:

#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 AND is not the root view controller
    if (viewController == self.viewControllers.firstObject)
    {
        if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)])
            self.interactivePopGestureRecognizer.enabled = NO;
    }
    else
    {
        if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)])
            self.interactivePopGestureRecognizer.enabled = YES;
    }
}
@end

目标-C

我遇到了同样的问题,这是我的解决方案:在自定义导航控制器中,如MYNavigationController,因为您将手势委托设置为导航控制器,因此可以在此处添加委托方法:

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{
    if (self.viewControllers.count>1) {
        return YES;
    }
    return NO;
}
然后,当它在根视图中时,它将停止弹出操作控制器并避免冻结行为。

即使我也有同样的问题,我也通过修改您引用的链接中提供的代码来修复它。现在我的屏幕很少冻结,仍然找到永久修复。

@implementation PPNavigationController
-(void)viewDidLoad
{
    //[super viewDidLoad];
    // Do any additional setup after loading the view.
     __weak PPNavigationController *weakSelf = self;
    if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)])
    {
        self.interactivePopGestureRecognizer.delegate = weakSelf;
        self.delegate = weakSelf;
    }
}

-(void)navigationController:(UINavigationController *)navigationController
       didShowViewController:(UIViewController *)viewController
                    animated:(BOOL)animate
{
    // Enable the gesture again once the new controller is shown
    if ([self respondsToSelector:@selector(interactivePopGestureRecognizer)])
        self.interactivePopGestureRecognizer.delegate = viewController;
}
Don't use this method
//-(void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated{
//}

这是我对这里提出的类似问题的回答

您可以使用一个小技巧来使本机手势正常工作。创建 UINavigationItem 的子类,然后覆盖leftBarButtonItems方法:

- (NSArray*)leftBarButtonItems
{
    return nil;
}

现在将此类用于具有自定义左UIBarButtonItem的项目。手势有效!这是因为UINavigationController认为没有剩余的物品并启用了该手势。您仍然可以通过 leftBarButtonItem 属性访问自定义项。

这里有一个简单的 Swift 子类,你可以使用它UINavigationController,我改编自@weak的答案。不需要实现UIGestureRecognizerDelegate,因为导航委托的navigationController(_:didShow:animated:)处理启用和禁用弹出手势的工作。

情节提要或代码中使用此子类比在 nav 控制器中嵌入的其他控制器中执行一次性禁用更容易。

import UIKit
@objc class LWNavigationController : UINavigationController,
                                     UINavigationControllerDelegate {
    override func viewDidLoad() {
        self.delegate = self
    }
    override func pushViewController(_ viewController: UIViewController,
                                     animated: Bool) {
        // Disable this gesture while animating a push.
        self.interactivePopGestureRecognizer?.isEnabled = false
        super.pushViewController(viewController, animated: animated)
        debugPrint("------(#function) (viewController)------")
    }
    // MARK: - UINavigationControllerDelegate
    func navigationController(_ navigationController: UINavigationController,
                              didShow viewController: UIViewController,
                              animated: Bool) {
        if (viewController == self.viewControllers.first) {
            // Keep the gesture disabled if we're at the root to avoid back swipes
            // from corrupting the navigation stack.
            self.interactivePopGestureRecognizer?.isEnabled = false
        } else {
            self.interactivePopGestureRecognizer?.isEnabled = true
        }
        debugPrint("------(#function) (viewController) " +
                   "enabled: (self.interactivePopGestureRecognizer?.isEnabled)" +
                   "------")
    }
}

相关内容

  • 没有找到相关文章

最新更新