iOS开发:UINavigationController自定义返回按钮,系统导航支持侧滑返回

Posted wuwuFQ

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS开发:UINavigationController自定义返回按钮,系统导航支持侧滑返回相关的知识,希望对你有一定的参考价值。

当你使用系统导航想拦截用户返回事件时,无法拦截侧滑返回
当你自定义导航或者隐藏导航后,ios系统导航的侧滑返回就失效了,那么用户体验将大打折扣
网上大部分自定义导航的解决方案是:给页面添加全局的轻扫手势,那么又区别于原生系统,改变了用户的操作习惯

在开发过程中,你是否也遇到了这样的困惑呢?希望这篇文章可以解决你的困惑!


自定义返回按钮

  1. 自定义一个导航的基类,继承于UINavigationController

    @interface FQBaseNavigationController : UINavigationController
    	
    @end
    
  2. 遵循导航代理协议

    @interface FQBaseNavigationController ()<UINavigationControllerDelegate>
    
    @end
    
    - (void)viewDidLoad 
    	[super viewDidLoad];
    	self.delegate = self;
    
    
  3. 自定义返回按钮

    • 在系统代理里自定义按钮
      leftBarButtonItem你可以自定义成图片,按钮,文本。
    - (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated 
    	UIViewController *root = navigationController.viewControllers[0];
    
    	if (root != viewController) 
    		UIBarButtonItem *itemleft = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"icon_back"] style:UIBarButtonItemStylePlain target:self action:@selector(backBarAction)];
    		viewController.navigationItem.leftBarButtonItem = itemleft;
    	
    
    
    • 实现点击返回按钮事件🔙
      在这里可以拦截点击返回事件,子类需要实现navigationShouldPopOnBackButton
    - (void)backBarAction 
    	 BOOL shouldPop = YES;
    	 UIViewController* vc = [self topViewController];
    	 if([vc respondsToSelector:@selector(navigationShouldPopOnBackButton)]) 
         shouldPop = [vc navigationShouldPopOnBackButton];
    	  
    	 if (shouldPop) 
      	 [self popViewControllerAnimated:YES];
    	 
    	
    

    继续往下看↓↓↓🔽↓↓↓🔽↓↓↓

支持系统侧滑返回

我们先来认识一个属性 interactivePopGestureRecognizer

The gesture recognizer responsible for popping the top view controller off the navigation stack.
负责从导航堆栈中弹出顶部视图控制器的手势识别器。

当我们自定义导航返回按钮和隐藏导航的时候,interactivePopGestureRecognizer 的代理就变成了 nil

  1. 自定义一个控制器基类,继承于UIViewController

    @interface FQBaseViewController : UIViewController
    
    @end
    
  2. 在基类里面拿到导航返回手势的代理

    - (void)viewDidAppear:(BOOL)animated 
     [super viewDidAppear:animated];
     if (self.navigationController && self.navigationController.viewControllers.count > 1 && [self.navigationController respondsToSelector:@selector(interactivePopGestureRecognizer)]) 
    	    self.navigationController.interactivePopGestureRecognizer.delegate = (id)self;
      
    
    
  3. 侧滑手势响应

    /// 侧滑手势响应
    - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer 
        return [self navigationShouldPopOnBackButton];
    
    

拦截导航返回事件

  1. UIViewController写个分类,并加一个可选协议,.m文件什么也不用写

    @protocol BackButtonHandlerProtocol <NSObject>
    @optional
    // 重写下面的方法以拦截导航栏返回按钮点击事件,返回 YES 则 pop,NO 则不 pop
    - (BOOL)navigationShouldPopOnBackButton;
    @end
    
    @interface UIViewController (BackButtonHandler) <BackButtonHandlerProtocol>
    
    @end
    
  2. 在需要拦截事件的控制器里,实现navigationShouldPopOnBackButton

    	/// 拦截页面侧滑和点击导航返回事件
    - (BOOL)navigationShouldPopOnBackButton
    
        if (...)
            //...这里处理业务逻辑
            return NO;
        
        return YES;
    
    

Nice!END!

以上是关于iOS开发:UINavigationController自定义返回按钮,系统导航支持侧滑返回的主要内容,如果未能解决你的问题,请参考以下文章

功能差异,UINavigationController vs Only Storyboard Segue

在 UINavigationController 中设置自定义导航栏类

在 UINavigationController 中设置自定义导航栏类

在 Swift 2.0 中设置 UINavigationController 栏标题

UINavigationController -> UIViewController -> UIView -> UITableViewController?

用动画隐藏导航控制器和标签栏控制器