UIView - "父级用户互动已启用"为false,但对于儿童为真?

mor*_*des 57 cocoa-touch uiview ios

看来父视图上的userInteractionEnabled = NO将阻止用户在所有子视图上进行交互.它是否正确?有没有办法解决?

laz*_*ycs 36

这是正确的,父视图上的userInteractionEnabled设置为NO将向下级联到所有子视图.如果您需要某些子视图以启用交互,而不启用其他子视图,则可以将子视图分成两个父视图:一个使用userInteractionEnabled = YES,另一个使用NO.然后将这两个父视图放在主视图中.

  • 谢谢懒惰。我的想法是使用透明视图来管理少数相关弹出菜单类型视图的布局。但是,如果看不见的布局视图阻止了与其下方内容的交互,那么这对我将不起作用。嗯... (2认同)
  • @orion你当然可以这样做,但它不会有用,因为iOS中的触摸从子视图到父视图.如果父视图收到触摸,则表示该子视图已经忽略它. (2认同)

小智 16

您可以将UIView子类化并覆盖hitTest:withEvent:以将触摸事件传递给您指定的视图(_backView):

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    UIView *view = [super hitTest:point withEvent:event];

    if (view == self) {
        view = _backView;
    }

    return view;
}
Run Code Online (Sandbox Code Playgroud)

如果触摸事件由该视图处理,则它将被传递给"_backView"(可以是IBOutlet,以便可以使用界面构建器进行设置); 如果要由任何子视图处理,只需返回该子项(结果[super hitTest:point withEvent:event];)

只要您知道将事件传递给哪个视图,此解决方案就可以了.除了不知道它是否有问题,因为我们返回的视图(_backView)不是当前UIView的子视图!但它在我的情况下运作良好.

一个更好的解决方案可能是中提到的一个 禁用倒是UIView的背景,使较低的意见按钮点击有其提到使用-pointInside:withEvent:; 与之前的解决方案相比,它更好的方式是您不需要指定'_backView'来接收事件(事件只是传递给链中的下一个视图)!缺点可能是我们需要-pointInside:withEvent:对所有子视图执行(虽然可能是可忽略的开销)