superview的手势应该取消iOS 7中的子视图的手势?

几年以来,我一直在假设,如果一个超级观点和它的子视图都有手势识别器,子视图将首先接收触摸并取消超级观点的手势。 直到iOS 7这个假设从来没有让我失望,让我添加手势子视图相信超级观点的手势不会干涉。 但是在iOS 7中,超级视图会先随机接收触摸并取消子视图的手势。 这种情况很less发生,这使问题很难被发现。

我第一次遇到这个问题,作为无法使用UITapGestureRecognizer窃听的UITapGestureRecognizer …再次,很less。 通常button将工作,直到他们没有。 让你质疑你的理智。 所以我推出了我自己的TapGestureRecognizer ,发现TapGestureRecognizer水龙头有时会取消他们的子视图的水龙头。 这在以前的iOS版本中从来没有这样做过,但是我想知道这种行为是否从未被承诺过。

我以为子视图的手势应该取消它的超级查看手势(除非委托人另有规定)。 这是错的还是这是一个错误?

请注意:我不是问如何处理这种情况。 我问,如果有人知道我的假设是不正确的。 我已经重新排列视图,dynamic地添加/删除手势,并创buildgestureRecognizer:shouldReceiveTouch:相当复杂的实现gestureRecognizer:shouldReceiveTouch:纠正这种情况。 这并不好玩,但我可以解决这个问题。

经过大量的search后,我发现与其他用户有问题的苹果留言板讨论: 与UITapGestureRecognizer问题 (需要开发者帐户)。 我继续并提交了一个错误报告:15331126 (有谁知道如何链接到错误报告了?) 。 同时,我实施了这个解决方法。 到目前为止,它似乎正在工作,但由于错误是如此罕见,我可能根本没有触发它。 我将它发布给我的testing版用户,如果我没有收到他们的投诉(谁在抱怨),我会认为这解决了这个问题。

更新:这个解决scheme已经解决了这个问题。 经过数十名用户使用数星期后,我还没有一个手势问题。

我的大部分手势都是自定义的。 我改变了他们自己的代表和实施:

 - (BOOL) gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{ if (gestureRecognizer == self){ if ([otherGestureRecognizer isMemberOfClass:self.class]){ if ([self isGestureRecognizerInSuperviewHierarchy:otherGestureRecognizer]){ return YES; } else if ([self isGestureRecognizerInSiblings:otherGestureRecognizer]){ return YES; } } } return NO; } 

请注意,我的自定义gestureRecognizers现在实现UIGestureRecognizerDelegate协议(公开,因为你会看到下面的原因)。 我还为UIGestureRecognizer(在上面的代码中使用)添加了几个类别:

 - (BOOL) isGestureRecognizerInSiblings:(UIGestureRecognizer *)recognizer{ UIView *superview = self.view.superview; NSUInteger index = [superview.subviews indexOfObject:self.view]; if (index != NSNotFound){ for (int i = 0; i < index; i++){ UIView *sibling = superview.subviews[i]; for (UIGestureRecognizer *viewRecognizer in sibling.gestureRecognizers){ if (recognizer == viewRecognizer){ return YES; } } } } return NO; } - (BOOL) isGestureRecognizerInSuperviewHierarchy:(UIGestureRecognizer *)recognizer{ if (!recognizer) return NO; if (!self.view) return NO; //Check siblings UIView *superview = self.view; while (YES) { superview = superview.superview; if (!superview) return NO; for (UIGestureRecognizer *viewRecognizer in superview.gestureRecognizers){ if (recognizer == viewRecognizer){ return YES; } } } } 

我不完全确定,我需要检查兄弟姐妹,因为我只看到超级观点手势发生的问题。 但是,我不想冒这个机会。 请注意,我只检查当前视图的“下方”的同胞,因为我不想取消当前视图上方的视图手势。

我不得不为自定义自定义识别器的代理添加实现,但是他们几乎只是callback到gestureRecognizer:

 - (BOOL) gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{ if ([gestureRecognizer respondsToSelector:@selector(gestureRecognizer:shouldBeRequiredToFailByGestureRecognizer:)]){ return [(id <UIGestureRecognizerDelegate>)gestureRecognizer gestureRecognizer:gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:otherGestureRecognizer]; } return NO; } 

希望这可以帮助其他人解决问题。