在平常的需求中难免会碰到多个手势冲突的问题,scrollView嵌套tableView, 或者多个页面多个手势,需要在某些条件下允许某个页面滑动,这个时候就需要解决手势冲突问题。
首先要搞清楚手势的几个BOOL值和代理方法
属性默认为YES,当这个属性设置为YES时,如果识别到了手势,系统将会发送touchesCancelled:withEvent:消息在其时间传递链上,终止触摸事件的传递,设置为NO,则不会终止事件的传递
@property(nonatomic) BOOL cancelsTouchesInView;
默认属性为NO,在触摸开始的时候,就会发消息给事件传递链,如果设置为YES,在触摸没有被识别失败前,都不会给事件传递链发送消息
@property(nonatomic) BOOL delaysTouchesBegan;
默认属性为YES, 是立刻发送touchesEnded消息到事件传递链或者等待一个很短的时间后,如果没有接收到新的手势识别任务,再发送
@property(nonatomic) BOOL delaysTouchesEnded;
手指触摸屏幕后回调的方法,返回NO则不再进行手势识别,方法触发等
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch;
开始进行手势识别时调用的方法,返回NO则结束,不再触发手势
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer;
默认为No,是否支持多时候触发,返回YES,则可以多个手势一起触发方法,返回NO则为互斥
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;
这个方法返回YES,第一个手势和第二个互斥时,第一个会失效
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer NS_AVAILABLE_IOS(7_0);
这个方法返回YES,第一个和第二个互斥时,第二个会失效
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer NS_AVAILABLE_IOS(7_0);
假如现在有个tableView加在scrollView上,需求让scrollView滚动到一定位置后在响应table的滚动事件,如下图:
ScreenRecording_05-30-2019 22-44-16.gif
首先,手势默认是互斥的,由事件的响应链可知,如果当前事件有被处理,那么事件将不会继续向上传递,意味着如果滑动tableView,父试图scrollView是不会响应的,显然就不是我们想要的。所以首先就需支持多手势
//识别多手势
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
然后就是一些细节处理,在scrollView的代理方法里边设置边界值,进行简单的逻辑处理,滑动到某一个值就停下来
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
//设定一个滑动边界
CGFloat bound_y = 100;
CGFloat offset_y = scrollView.contentOffset.y;
if(offset_y >= bound_y){
_mainCanScroll = NO;
self.segment.tableCanScroll = YES;
}else{
self.segment.tableCanScroll = NO;
}
if(!_mainCanScroll){
self.scrollView.contentOffset = CGPointMake(0, bound_y);
}
CGFloat add_y = offset_y;
if(add_y>bound_y || !_mainCanScroll)add_y=bound_y;
[self.segment.view mas_updateConstraints:^(MASConstraintMaker *make) {
make.height.mas_equalTo(kScreen.height-150+add_y);
}];
self.scrollView.showsVerticalScrollIndicator = _mainCanScroll;
}
这里只是简单的一个demo,对手势冲突的一个简单处理,欢迎讨论。
附上Demo
网友评论