现在有一个Aview,和一个子视图的子视图bview;两个不同事件的长按手势AG,bG。长按A区域需要响应AG,但是按到了b区域的时候,需要响应bG。发现网上很多资料都不是这个情况,所以你会怎么做?
1、如何定义
处理肯定是要在手势代理里去处理的。一般同一个view上的手势冲突都在这个代理里处理,多次调用。
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer;
但是如何定义呢?一开始我这样定义两个手势
UILongPressGestureRecognizer *homeLong = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(homeLongGes)];
homeLong.delegate = self;
[self.view addGestureRecognizer:homeLong];
UILongPressGestureRecognizer *timeLong = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(timeLongGes)];
timeLong.delegate = self;
[_countDown.titleLabel addGestureRecognizer:timeLong];
在同一个控制器中,代理只会走一次。然后我换成了
第二次定义两个手势
UILongPressGestureRecognizer *homeLong = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(homeLongGes)];
homeLong.delegate = self;
[self.view addGestureRecognizer:homeLong];
UILongPressGestureRecognizer *timeLong = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(timeLongGes)];
timeLong.delegate = self;
[self.view addGestureRecognizer:timeLong];
此时代理调用两次了,说明要开始判断两个手势了。
2、代理处理
首先要说的一点是,假如代理里直接return YES,那么最后的手势会进行响应,最先定义的不会响应,假如NO,则都不响应。
这样则说明点到b区域,又是b手势的时候 return yes,否则返回no。
既然位置不同,很正常的第一个想到的是:肯定需要判断点击位置来处理。那么代理中这样处理
if (CGRectContainsPoint(_countDown.timeLabel.frame,[gestureRecognizer locationInView:_countDown])) {
return YES;
}
else if (!CGRectContainsPoint(_countDown.frame,[gestureRecognizer locationInView:self.view])) {
return YES;
}
return NO;
乍看是没问题,其实这样写,每次都返回YES,就跟之前的情况一样了。
所以我们还得加个判断,就是在这个区域中,还得是这个区域的这个手势。
那你可能会想到给手势一个标示,tag,但是手势不是继承view,所以给不了tag。看了UIGestureRecognizer的API,有个view,可以给手势的view加tag,但是我们又是同一个view,所以手势也区别不了,那怎么办?
在这里我想了很久。。当时还没想到,还是过几天突然想到的。。就是我想手势分配的内存地址肯定不一样,我用内存地址不就可以吗,又突然想到,内存地址的话,我把两个成员变量定义成两个局部变量来用不就可以了吗。然后我修改了代码。
if (CGRectContainsPoint(_countDown.timeLabel.frame,[gestureRecognizer locationInView:_countDown]) && gestureRecognizer == _timeTap) {
return YES;
}
else if (!CGRectContainsPoint(_countDown.frame,[gestureRecognizer locationInView:self.view]) && gestureRecognizer == _homeTap) {
return YES;
}
return NO;
需要注意的是:上述代理中第一个if,是根据你手势在b父视图位置的与b视图大小是否包含来判断的。
这样就成功了,假如你的手势事件还需要一些复杂的操作,你可以再加一些标示来判断代理是否需要返回 NO。
_本站文章为 宝宝巴士 SD.Team 原创,转载务必在明显处注明:(作者官方网站: 宝宝巴士 ) __转载自【宝宝巴士SuperDo团队】原文链接: http://www.jianshu.com/p/db4247c1934a