当你使用系统导航想拦截用户返回事件时,无法拦截侧滑返回 当你自定义导航或者隐藏导航后,iOS系统导航的侧滑返回就失效了,那么用户体验将大打折扣 网上大部分自定义导航的解决方案是:给页面添加全局的轻扫手势,那么又区别于原生系统,改变了用户的操作习惯
在开发过程中,你是否也遇到了这样的困惑呢?希望这篇文章可以解决你的困惑!
自定义返回按钮
自定义一个导航的基类,继承于UINavigationController @interface FQBaseNavigationController : UINavigationController
@end
遵循导航代理协议 @interface FQBaseNavigationController ()
@end
- (void)viewDidLoad {
[super viewDidLoad];
self.delegate = self;
}
自定义返回按钮
在系统代理里自定义按钮 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。
自定义一个控制器基类,继承于UIViewController @interface FQBaseViewController : UIViewController
@end
在基类里面拿到导航返回手势的代理 - (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;
}
}
侧滑手势响应 /// 侧滑手势响应
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
return [self navigationShouldPopOnBackButton];
}
拦截导航返回事件
给UIViewController写个分类,并加一个可选协议,.m文件什么也不用写 @protocol BackButtonHandlerProtocol
@optional
// 重写下面的方法以拦截导航栏返回按钮点击事件,返回 YES 则 pop,NO 则不 pop
- (BOOL)navigationShouldPopOnBackButton;
@end
@interface UIViewController (BackButtonHandler)
@end
在需要拦截事件的控制器里,实现navigationShouldPopOnBackButton /// 拦截页面侧滑和点击导航返回事件
- (BOOL)navigationShouldPopOnBackButton
{
if (...){
//...这里处理业务逻辑
return NO;
}
return YES;
}
Nice!END!
推荐链接
发表评论