在自定义UINavigationController中,利用系统自带左边缘滑动手势实现全屏幕都可以点击滑动
1.防止手势冲突
self.interactivePopGestureRecognizer.enabled = NO;
2.给自定义UINavigationController的view添加手势
让'self.interactivePopGestureRecognizer.delegate'监听滑动事件
实现系统内部方法(po xx手势):'handleNavigationTransition:'
UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]
initWithTarget:self.interactivePopGestureRecognizer.delegate
action:@selector(handleNavigationTransition:)];
3.再将自定义手势的代理设置为控制器
pan.delegate = self;
[self.view addGestureRecognizer:pan];
实现代理方法,例如:
如果不是第一个控制器就可以滑动
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
// 手势何时有效 : 当导航控制器的子控制器个数 > 1就有效
return self.childViewControllers.count > 1;
}
解决系统返回手势与scrollView滑动手势冲突问题
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
// 首先判断响应gestureRecognizer的view是不是系统UILayoutContainerView
if ([gestureRecognizer.view isKindOfClass:NSClassFromString(@"UILayoutContainerView")]) {
// 如果otherGestureRecognizer的响应者是UIScrollView,
// 再判断otherGestureRecognizer的state是began,
// 同时判断scrollView的位置是不是正好在最左边
// 满足条件即可实现返回手势
if ([otherGestureRecognizer.view isKindOfClass:[UIScrollView class]]) {
UIScrollView *scrollView = (UIScrollView *)otherGestureRecognizer.view;
if (otherGestureRecognizer.state == UIGestureRecognizerStateBegan &&
scrollView.contentOffset.x == 0) {
return YES;
}
}
}
return NO;
}
进入某个页面禁止手势后可以重写系统方法,恢复手势响应
- (NSArray<UIViewController *> *)popToRootViewControllerAnimated:(BOOL)animated
{
self.interactivePopGestureRecognizer.enabled = YES;
return [super popToRootViewControllerAnimated:animated];
}
如何解决导航控制器pop手势失效
成为手势代理
self.interactivePopGestureRecognizer.delegate = self;
实现需要的代理方法(基本同上),例如:
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
// 手势何时有效 : 当导航控制器的子控制器个数 > 1就有效
return self.childViewControllers.count > 1;
}