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

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

但是,如果superview的userInteractionEnabled设置为NO,那么所有的子视图和后代也都禁用了用户交互? 如果我们只想禁用主视图但不想禁用子视图呢?

你不能这样做,

相反,你会改变你的意见的安排,如下所示:

 Main View-> subViews 

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

所以你目前的主视图和你目前的子视图将成为兄弟姐妹,一个新的容器视图的孩子

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

userInteractionEnabled

如果设置为NO,则该视图(及其子视图)不被接收。 触及这个观点或其中的一个子观点“落后”到它的背后。

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

窗口对象使用命中testing和响应者链来查找接收触摸事件的视图。 在命中testing中,窗口调用hitTest:withEvent:在视图层次结构的最顶层视图上; 此方法通过recursion调用pointInside:withEvent:在视图层次结构中的每个视图中返回YES,继续向下继续,直到find触摸发生的边界内的子视图。 这个观点成为了命中testing的观点。

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

你可以重写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 } } 

第一种方法

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