NSButton RadioGroup (NSMatrix Alternative)

倖福魔咒の 提交于 2019-12-12 08:26:11

问题


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:


Alternative solution without third party frameworks, without creating an array and without any repeat loop.

  • In Interface Builder add 5 Radio Button objects.
  • Assign tags to the buttons for example starting with 100.
  • Set the state of one button as default to ON, the other states to OFF.
  • Add @IBOutlet variables in the target class and connect the buttons.

    @IBOutlet weak var button1: NSButton!
    @IBOutlet weak var button2: NSButton!
    @IBOutlet weak var button3: NSButton!
    @IBOutlet weak var button4: NSButton!
    @IBOutlet weak var button5: NSButton!
    
  • Add a variable currentOnStateButton which contains the reference to the button which is currently selected.

    weak var currentOnStateButton : NSButton!
    
  • In viewDidLoad or similar early called method assign the default button reference to the currentOnStateButton variable.

    currentOnStateButton = button1
    
  • Add this activityButtonPressed IBAction method and connect the actions of all buttons to it, the doActionForButtonx() methods are dummy methods.

    @IBAction func activityButtonPressed(sender: NSButton) {
    
      currentOnStateButton.state = NSOffState
      sender.state = NSOnState
      currentOnStateButton = sender
      switch sender.tag {
        case 100: doActionForButton1()
        case 101: doActionForButton2()
        case 102: doActionForButton3()
        case 103: doActionForButton4() 
        case 104: doActionForButton5() 
        default : break
      }
    }
    



回答4:


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



来源:https://stackoverflow.com/questions/30530326/nsbutton-radiogroup-nsmatrix-alternative

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!