繁体   English   中英

在 iOS 上,如果超级视图的 userInteractionEnabled 为 NO,那么所有子视图也会被禁用?

[英]On iOS, if a superview's userInteractionEnabled is NO, then all subviews are disabled as well?

我认为当一个视图被触摸或点击时,它的处理程序首先被调用,然后它的超级视图的处理程序被调用(向上传播)。

但是,如果超级视图的userInteractionEnabled设置为 NO,那么所有子视图和后代也将禁用用户交互, userInteractionEnabled是真的吗? 如果我们只想禁用主视图但不想禁用子视图怎么办?

您可以覆盖hitTest(_:withEvent:)以忽略视图本身,但仍会对其子视图进行触摸。

class ContainerStackView : UIStackView {
    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        let result = super.hitTest(point, with: event)
        if result == self { return nil }
        return result
    }
}

如果这可能有帮助,我在 Matt Neuburg 的 Programming iOS 5 中找到了这一点,第 10 页。 467:

userInteractionEnabled

如果设置为 NO,这个视图(连同它的子视图)被排除在接收触摸之外。 触摸此视图或其子视图之一“落入”其后面的视图。

此外,Apple 的 iOS 事件处理指南说:

window对象使用hit-testing和响应链来寻找接收触摸事件的视图。 在命中测试中,一个窗口在视图层次结构的最顶层视图上调用 hitTest:withEvent: ; 此方法通过递归调用 pointInside:withEvent: 在视图层次结构中返回 YES 的每个视图上继续进行,向下进行层次结构,直到找到发生触摸的边界内的子视图。 该视图成为命中测试视图。

和编程 iOS 5 by Matt Neuburg, p.485 提到如果一个视图被标记为userInteractionEnabledNO ,或hiddenYES ,或者不透明度接近 0,那么视图及其子视图将不会被HitTest遍历(因此不会考虑任何触摸)。

更新:我想如果我们考虑其他场景中的亲子情况,它也会以这种方式工作。 例如,在 HTML 中,如果有一个div并且这个div下都有子级,现在这个div设置为display: none ,那么所有子级都没有显示是有道理的。 因此,如果父母设置为不与用户交互,那么孩子也不与用户交互也是有道理的。

你不能那样做

相反,您可以更改视图的排列,如下所示:

Main View -> subViews

Container View -> Main View that you want to set as inactive
               -> other views that you want to still be active

所以你当前的主视图和你当前的子视图将成为新容器视图的兄弟姐妹

第一种方法

- (BOOL) gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
  if ([touch.view.superview isKindOfClass:[SuperViewParent class]]) return FALSE;
  return TRUE;
}

第二种方法

UITapGestureRecognizer *r = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(agentPickerTapped:)];
    r.cancelsTouchesInView = NO;
    [agentPicker addGestureRecognizer:r];

暂无
暂无

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

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