NSButton RadioGroup (NSMatrix Alternative)

2020-07-06 04:14发布

问题:

I've tried a few times to set up several similar buttons, all connected to the same IBActions, and still can't seem to replicate the RadioButton Behaviour.

At the moment, I have 5 Buttons, all children of one NSView..

NSView
    - ButtonOne - NSButton (Square Button)
    - ButtonTwo - NSButton (Square Button)
    - ButtonThree - NSButton (Square Button)
    - ButtonFour - NSButton (Square Button)
    - ButtonFive - NSButton (Square Button)

They're all connected to a common IBAction, which reads as:

@IBAction func activityButtonPressed(sender: NSButton) {

    println("\(sender.title) Pressed")

}

Which works to the point where the actual mosueDown events are caught and sent to the func (as expected)..

how do I get them working in the Radio Button mode? i.e. have their NSOnState and NSOffState toggle when the various buttons are clicked?

When I try and change the button type to Radio Button, it automatically flips back to "Switch"....

Cheers,

A

回答1:

Since you specifically don't want to use NSMatrix... First issue is that if you are using square button style, you can't use radio type. You want to use the On Off type in Interface Builder.

Here is the code I used for 4 buttons to test this out:

var buttonList : [NSButton] {
    return [button1, button2, button3, button4]
}

@IBAction func buttonPressed(sender: NSButton) {
    buttonList.forEach {
        $0.state = $0 == sender ? .on : .off
    }
}

As you can see, it iterates over all of the buttons, testing if it is the button that was pressed. It turns that button on while turning the other buttons off. You will need to manage any state you want from there, or by checking the state of all of the buttons:

func whichButton() -> ActivityState {
   if button1.state == .on { return .one }
   if button2.state == .on { return .two }
   ...
}

where ActivityState.one is some enum case that you can use to determine which state you are in.



回答2:

just give the NSRadioButtons the same superview and action. And as noted by Good Doug in his answer,

[…] if you are using square button style, you can't use radio type. You want to use the On Off type in Interface Builder.

I really don't think you want to have your action method set the state of all buttons in the group… let AppKit do that for you.

From OS X Developer Release Notes: Cocoa Application Framework (10.10 and Earlier)

An NSButton configured as a radio button (with the -buttonType set to NSRadioButton), will now operate in a radio button group for applications linked on 10.8 and later. To have the button work in a radio group, use the same -action for each NSButton instance, and have the same superview for each button. When these conditions are met, checking one button (by changing the -state to 1), will uncheck all other buttons (by setting their -state to 0).



回答3:

I believe that you are looking for NSMatrix:

You can configure this with as many rows and columns as you like:

You can then choose whether to allow a single choice or a variety:

You capture the selection in your IBAction with any combination of sender.selectedColumn and sender.selectedRow