1
votes

So I am creating a subclassed NSButton that has a custom look for the on/off state.

To do so, I overrided -mouseDown and -mouseUp, and modified the view accordingly.

Now in the view controller that owns the button, I have an IBAction connected to this custom button.

The problem is that when I overrided the NSResponder methods, the IBAction never gets called unless I call [super mouseDown] within the overrided -mouseDown method.

But if I call [super mouseDown], the custom button doesn't receive the -mouseUp event (and the UI doesn't update back into the off/unpressed state).

I've tried a few things, but this seems like a common thing people would have customized, and it should be easier than I'm making it.

I was thinking of creating a block property on the custom button called pressedAction, and when the view controller is instantiated, set that block property on the button with the code I would have had in the IBAction. Then inside of the custom button, I would just execute this block in the -mouseUp method

But that solution seems a little weird because to me a subclassed NSButton should be able to fire IBActions

1

1 Answers

1
votes

I have done this a couple of ways in the past. Instead of overriding -mouseDown and -mouseUp I used the views layer and the NSCell property

isHighlighted

Your NSButton subclass would look like this

- (BOOL)wantsUpdateLayer
{
    return YES;
}

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

Or instead of subclassing NSButton you can subclass NSButtonCell and override - (void)drawBezelWithFrame:(NSRect)frame inView:(NSView *)controlView

and again use the isHighlighted property

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

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