iOS 的手势均继承自 UIGestureRecognizer,使用多个手势的过程中可能遇到以下几种情况。
1. 多个互相冲突 gesture
如果直接向一个 view 添加多个互相冲突的同类 gesture,比如 TapGesture 的单击手势,则后添加的会覆盖前面的,在识别过程中只会触发最后一个事件。
UITapGestureRecognizer *singleTapRecongnizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTap:)];
singleTapRecongnizer.numberOfTapsRequired = 1;
UITapGestureRecognizer *singleTapRecongnizer1 = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTap1)];
UITapGestureRecognizer *singleTapRecongnizer2 = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTap2)];
UIGestureRecognizer *singleTapRecongnizer3 = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(singleTap3)];
[self.bigImageView addGestureRecognizer:singleTapRecongnizer];
[self.bigImageView addGestureRecognizer:singleTapRecongnizer1];
[self.bigImageView addGestureRecognizer:singleTapRecongnizer3];
[self.bigImageView addGestureRecognizer:singleTapRecongnizer2];
此时要设置 gesture 的代理方法
// called when the recognition of one of gestureRecognizer or otherGestureRecognizer would be blocked by the other
// return YES to allow both to recognize simultaneously. the default implementation returns NO (by default no two gestures can be recognized simultaneously)
//
// note: returning YES is guaranteed to allow simultaneous recognition. returning NO is not guaranteed to prevent simultaneous recognition, as the other gesture's delegate may return YES
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;
此方法如果返回 YES 就可以同时触发两个互相冲突的手势,要注意,由于其他 gesture 的代理方法可能返回 YES,所以单独一个 gesture 的代理方法返回 NO 可能并没有效果。
2. 互不冲突 gesture
对于互相不冲突的手势,分为两种典型情况
- 单击与双击:同类 gesture,但触发条件不同,双击时单击与双击事件都会触发
- 单击与滑动:不同类 gesture,只会触发其中之一
此时如果要实现同一时刻只触发一个事件,则可以选择
- 直接设置 gesture 的属性
[singleTapRecongnizer requireGestureRecognizerToFail:doubleTapRecongnizer];
- 设置代理方法
// called once per attempt to recognize, so failure requirements can be determined lazily and may be set up between recognizers across view hierarchies
// return YES to set up a dynamic failure requirement between gestureRecognizer and otherGestureRecognizer
//
// note: returning YES is guaranteed to set up the failure requirement. returning NO does not guarantee that there will not be a failure requirement as the other gesture's counterpart delegate or subclass methods may return YES
// 返回 YES 则 gestureRecognizer 和 otherGestureRecognizer 冲突时第一个生效
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer NS_AVAILABLE_IOS(7_0);
// 返回 YES 则 gestureRecognizer 和 otherGestureRecognizer 冲突时第二个生效
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer NS_AVAILABLE_IOS(7_0);
要注意如果同时设置了 gesture 属性和代理方法,代理方法 可能会失效。
3. 子视图与父视图的手势
UIGestureRecognizerDelegate 中的方法并没有限制在同一个视图之中,所以,不同视图之间的手势关系与 1 和 2 的处理相同。