繁体   English   中英

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

[英]Should superview's gesture cancel subview's gesture in iOS 7?

几年来我一直在假设如果超视图及其子视图都具有手势识别器,子视图将首先接收触摸并取消超视图的手势。 直到iOS 7,这个假设从未让我失望,允许我向子视图添加手势,确信superview的手势不会干扰。 但是在iOS 7中,超级视图将首先随机接收触摸并取消子视图的手势。 这种情况很少发生,这使问题难以发现。

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

我认为子视图的手势应该取消它的superview的手势(除非委托另有指定)。 这是错的还是这个错误?

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

经过大量的搜索,我发现了Apple的留言板与其他用户有关此问题的讨论: UITapGestureRecognizer的问题 (需要开发人员帐户)。 我继续提交了一个错误报告:15331126 (有没有人知道如何链接到错误报告?) 与此同时,我实施了这种解决方法。 到目前为止它似乎正在起作用,但由于这个bug很少见,我可能还没有触发它。 我将它发布给我的测试版用户,如果我没有得到他们的抱怨(他们一直在抱怨),我会认为这可以解决问题。

更新:此解决方案已解决此问题。 经过数周用户数周的使用后,我没有一个手势问题。

我的大部分手势都是定制的。 我把它们改成了自己的代表并实施了:

- (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;
            }
        }
    }
}

我不完全确定我需要检查兄弟姐妹,因为我只看到superview手势出现问题。 但是,我不想抓住这个机会。 请注意,我只检查当前视图之下“兄弟姐妹”,因为我不想取消当前视图“上方”的视图手势。

我必须为那些将自己设置为自定义识别器的委托的类添加实现,但它们几乎只是回调给gestureRecognizer:

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM