制作具有 on/off 状态但仍处理 IBAction 的自定义 NSButton

Making a custom NSButton that has an on/off state, but still handles IBActions

所以我正在创建一个子类 NSButton,它具有 on/off 状态的自定义外观。

为此,我覆盖了 -mouseDown-mouseUp,并相应地修改了视图。

现在在拥​​有按钮的视图控制器中,我有一个 IBAction 连接到这个自定义按钮。

问题是当我重写 NSResponder 方法时,IBAction 永远不会被调用 除非 我在重写的方法中调用 [super mouseDown] -mouseDown 方法。

但是 如果我调用 [super mouseDown],自定义按钮不会收到 -mouseUp 事件(并且 UI 不会更新回 off/unpressed 状态)。

我已经尝试了一些东西,但这似乎是人们定制的常见东西,它应该比我做的更容易。

我正在考虑在名为 pressedAction 的自定义按钮上创建一个块 属性,然后在实例化视图控制器时,使用代码在按钮上设置该块 属性我会在 IBAction。然后在自定义按钮内部,我将在 -mouseUp 方法

中执行此块

但是这个解决方案似乎有点奇怪,因为对我来说子类化的 NSButton 应该能够触发 IBActions

我过去用过几种方法来做到这一点。我没有覆盖 -mouseDown 和 -mouseUp,而是使用了视图层和 NSCell 属性

isHighlighted

你的 NSButton 子类看起来像这样

- (BOOL)wantsUpdateLayer
{
    return YES;
}

- (void)updateLayer
{
    if ([self.cell isHighlighted]) {
        self.layer.contents = [NSImage imageNamed:@"OnStateImage"];
    } else {
        self.layer.contents = [NSImage imageNamed:@"OffStateImage"];
    }
}

或者不是子类化 NSButton 你可以子类化 NSButtonCell 并覆盖 - (void)drawBezelWithFrame:(NSRect)frame inView:(NSView *)controlView

再次使用 isHighlighted 属性

- (void)drawBezelWithFrame:(NSRect)frame inView:(NSView *)controlView {

    if (self.isHighlighted) {
        //Draw on State
    } else {
        //Draw off State
    }
}