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

时间:2012-06-04 11:57:45

标签: iphone ios uiview uikit uiresponder

我认为当触摸或点击视图时,首先调用其处理程序,然后调用其superview的处理程序(向上传播)。

但是如果superview的userInteractionEnabled设置为NO,那么所有子视图和后代也会因用户交互而被禁用吗?如果我们只想禁用主视图但又不想禁用子视图,该怎么办?

4 个答案:

答案 0 :(得分:23)

如果这可能会有所帮助,我在Matt Neuburg编程的iOS 5中发现了这一点。 467:

  

userInteractionEnabled

     

如果设置为NO,则从中排除此视图(及其子视图)   接受接触。触及此视图或其中一个子视图“堕落   通过“对它背后的观点。”

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

  

窗口对象使用命中测试和响应者链来查找   查看接收触摸事件。在命中测试中,窗口调用   hitTest:withEvent:在视图层次结构的最顶层视图上;这个   方法通过递归调用pointInside:withEvent:on each   视图层次结构中的视图返回YES,继续向下   层次结构,直到找到触摸范围内的子视图   发生。该视图成为热门测试视图。

和编程iOS 5由Matt Neuburg编写,第485页提到如果视图被标记为userInteractionEnabledNO,或hidden标记为YES,或者不透明度已接近为0,那么HitTest将不会遍历视图及其子视图(因此不会考虑任何触摸)。

答案 1 :(得分:19)

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

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

答案 2 :(得分:15)

你不能这样做,

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

Main View-> subViews

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

因此,您当前的主视图和当前的子视图将成为兄弟姐妹,新容器视图的子视图

答案 3 :(得分:1)

第一种方法

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