0%

嵌套页面手势冲突解决

BUG场景

mainTableView嵌套listTableView.mainTableView的headerView里有左右滑动的collectionView(eg:轮播图).此时mainTableView的下拉刷新就会和collectionView的左右滑动起冲突.collectionView左右滑时,mainTableView可能会跟着一起动.

为了实现吸顶效果,mainTableView是允许同时识别多个手势的.而这恰恰是引起手势冲突的原因.

1
2
3
4
5
6
7
8
@implementation MainTableView

// 允许多个手势
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
return YES;
}

@end

解决

由于mainTableView只能上下滑动,因此可以判断如果otherGestureRecognizer所在的view在左右滑动则不让mainTableView的手势同时识别.

这里有一个不好处理的地方就是在某些精心构造的滑动下,point可能为(0,0),

偶现时的日志:

1
2
3
4
5
6
7
8
9
2019-08-03 18:23:52.661593+0800 xxx[20938:1512558] 
view:<MainTableView: 0x1070c3c00; baseClass = UITableView; frame = (0 0; 414 623); clipsToBounds = YES; gestureRecognizers = <NSArray: 0x282b5dce0>; layer = <CALayer: 0x28258a980>; contentOffset: {0, -3.3333333333333335}; contentSize: {414, 1418}; adjustedContentInset: {0, 0, 0, 0}>
ges:<UIScrollViewPanGestureRecognizer: 0x106d75500; state = Changed; delaysTouchesEnded = NO; view = <GKPageTableView 0x1070c3c00>; target= <(action=handlePan:, target=<GKPageTableView 0x1070c3c00>)>>
otherView:<UICollectionView: 0x1079cea00; frame = (0 0; 414 165.6); clipsToBounds = YES; gestureRecognizers = <NSArray: 0x282b03930>; layer = <CALayer: 0x2825528c0>; contentOffset: {64584, 0}; contentSize: {124200, 165.60000000000002}; adjustedContentInset: {0, 0, 0, 0}> collection view layout: <UICollectionViewFlowLayout: 0x111c20eb0>
otherGes:<UIScrollViewPanGestureRecognizer: 0x106c7aaa0; state = Began; delaysTouchesEnded = NO; view = <UICollectionView 0x1079cea00>; target= <(action=handlePan:, target=<UICollectionView 0x1079cea00>)>; must-fail = {
<UIScrollViewPagingSwipeGestureRecognizer: 0x111c210d0; state = Failed; view = <UICollectionView 0x1079cea00>; target= <(action=_handleSwipe:, target=<UICollectionView 0x1079cea00>)>>
}>
2019-08-03 18:23:52.662988+0800 EmotionCounsel[20938:1512558]
移动的位置:{0, 7}

此时就没办法判断出otherGestureRecognizer.view是不是在左右滑动了.所以加了一个else判断避免这种情况.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
@implementation MainTableView

// 允许多个手势
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {

if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]] && [otherGestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]] && otherGestureRecognizer.view != self) {
UIPanGestureRecognizer *otherPanGes = (UIPanGestureRecognizer *)otherGestureRecognizer;
CGPoint point = [otherPanGes translationInView:otherPanGes.view];
UIGestureRecognizerState otherState = otherPanGes.state;
if (otherState == UIGestureRecognizerStatePossible || otherState == UIGestureRecognizerStateBegan) {
if (fabs(point.x) > 0) { //如果在水平左右滑动
return NO;
} else {
if ([otherGestureRecognizer.view isKindOfClass:[UICollectionView class]]) {
UICollectionView *otherView = (UICollectionView *)otherGestureRecognizer.view;
if ([otherView.collectionViewLayout isKindOfClass:[UICollectionViewFlowLayout class]] && [(UICollectionViewFlowLayout *)otherView.collectionViewLayout scrollDirection] == UICollectionViewScrollDirectionHorizontal) {
NSLog(@"正在滑动左右滚动视图!!!!!!");
return NO;
} else {
NSLog(@"UICollectionView的其他布局");
}
} else {
NSLog(@"其他视图");
}
}
}
}

return YES;
}


@end
觉得文章有帮助可以打赏一下哦!