描述
我们的iOS客户端有个页面,底层是UIPageController,也就是有个UIScrollview在底层。然后上层是三个控制器并列,每个控制器都是UITableView。在其中一个Cell里有放的是UICollectionView,产品要求CollectionView的滚动到最后的时候不能让PageController切换。也就是说,我需要拦截到UICollectionView的事件,不让它传递给UIScrollView。
视图层次
这个是简略的画法,其实还有很多层,主要的事件传递设计的是这俩而已。
处理思路
一般情况下遇到事件传递可以在hittest中处理返回的view,或者用手势的情况下,在手势的代理方法里做处理gestureenable。这里的情况较为特殊,因为collectionview在ScrollView之上,在CollectionView滚动到边缘之后就会将事件传递给父ScrollView处理,所以我们需要告诉响应链collectionview才是需要处理这件事情的。
这里我写了一个继承自UICollectionView的类专门用来处理事件传递与处理。首先得加上一个Tap手势用来拦截用户的手势事件,在一个重要的地方是也要写上将hitTest的view设置为self。然后就是在gestureRecognizerShouldBegin手势方法里判断是否需要相应在对应view上的手势。
具体代码如下:
@interface XTCollectionView()<UIGestureRecognizerDelegate>
@property (nonatomic,strong)UITapGestureRecognizer* gesture;
@end
@implementation XTCollectionView
- (void)didMoveToSuperview{
[super didMoveToSuperview];
[self gesture];
}
- (UITapGestureRecognizer *)gesture{
if (!_gesture) {
UITapGestureRecognizer* gest = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(gestAction:)];
[self addGestureRecognizer:gest];
_gesture = gest;
}
return _gesture;
}
- (void)gestAction:(UIGestureRecognizer*)gest{
}
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{
return self;
}
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{
UIView* view = gestureRecognizer.view;
if ([view isEqual:self] || [view isKindOfClass:[UITableView class]]) {
return YES;
}
return NO;
}
@end
记录一下,有这种需求的可以尝试。有什么关于iOS开发的问题也可以彼此交流。