防止禁用的UIButton传播触摸事件

Mih*_*ian 17 iphone cocoa-touch objective-c event-handling uibutton

我的应用程序有两个重叠的UIButton.顶部按钮有时可能被禁用.但是,在这种情况下,它接收的任何触摸事件似乎都传递给底层视图,在我的情况下是另一个按钮.

我需要的是顶部按钮拦截所有触摸并防止它们到达底部按钮,即使在禁用状态下(即使在禁用状态下调用指定的动作,我也会很高兴).

到目前为止,我已经尝试过:

[topButton setUserInteractionEnabled:YES];
Run Code Online (Sandbox Code Playgroud)

[topButton setExclusiveTouch:YES];
Run Code Online (Sandbox Code Playgroud)

虽然后一种情况可能是不受欢迎的,因为我仍然需要底部按钮来响应事件,如果它是第一个点击的视图.无论哪种方式,它们都不起作用.

kol*_*hiy 15

我将以下方法添加到禁用按钮的superview:

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    if (!self.watchButton.enabled &&
        [self.watchButton pointInside:[self convertPoint:point toView:self.watchButton]
                            withEvent:nil]) {
        return nil;
    }
    return [super hitTest:point withEvent:event];
}
Run Code Online (Sandbox Code Playgroud)

这适用于UITableView单元格.


Pat*_*nch 6

我设法通过上面@kolyuchiy的答案的略微修改的版本来按需进行此工作。我覆盖了子类中的hitTest:withEvent:方法UIButtonself在禁用时返回并且该点位于视图的框架之内,以便消耗触摸,但不调用按钮的事件处理。

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    if ( !self.enabled && [self pointInside:[self convertPoint:point toView:self] withEvent:event] )
    {
        return self;
    }
    return [super hitTest:point withEvent:event];
}
Run Code Online (Sandbox Code Playgroud)

迅捷版:

override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
    if !isEnabled, self.point(inside: point, with: event) {
        return self
    }
    return super.hitTest(point, with: event)
}
Run Code Online (Sandbox Code Playgroud)


Nim*_*rod 1

创建按钮的子类,然后重写这些方法,以便按钮捕获事件,但如果按钮的某些属性设置为 NO,则忽略它们:

touchesBegan:withEvent:
touchesCancelled:withEvent:
touchesEnded:withEvent:
touchesMoved:withEvent:
Run Code Online (Sandbox Code Playgroud)

这些是 UIResponder 的方法。

如果您希望处理事件,请让他们调用 [super ...] 方法,否则,如果您希望事件“被吃掉”,则不要调用它并返回。

如果有必要,另请参阅:Observinginchingmulti-touchgesturesinaUITableView