1

I'm creating a combo box programmatically and I would like to cause the selection from the drop down menu to call a function. I can do it if i'm creating a button using - myButton.action = #selector(some_function(_:)), but it doesn't work with an NSComboBox. here is an example from my code:

func populate_scroller_with_combobox(json_file: Array<Any>, panel: NSView)
{
    let combox = NSComboBox()
    combox.identifier = NSUserInterfaceItemIdentifier(rawValue: "combobox1")
    combox.addItem(withObjectValue: "None")
    combox.addItems(withObjectValues: json_file_content)
    combox.numberOfVisibleItems = 10
    combox.isEditable = false
    combox.action = #selector(some_function(_:))
    combox.selectItem(withObjectValue: "None")
    panel.addSubview(combox)
    combox.frame = CGRect(x:190, y: 30, width: 170, height: 26)
}

@objc func some_function(_ sender: NSButton)
{
    print ( "Combobox value changed." )
}

2 Answers2

0

It's been a looooonnnnggg time since I've used an NSComboBox.

Reviewing the docs, it seems to follow the data source & delegate pattern that table views use.

You need to have some object conform to the NSComboBoxDelegate protocol and set it as the combo box's delegate. Then your delegate's comboBoxSelectionDidChange(_:) method will be called when the user makes a selection.

You could create a custom NSControl that manages an NSComboBox and serves as the combo box's delegate, and have the control generate an IBAction with an event type of valueChanged when the user selects an item.

Duncan C
  • 128,072
  • 22
  • 173
  • 272
  • when looking at the options that I have I see that I can use the .action option, but nothing happens when I change the selected item of the combo box. is there a different way to make the .action to work? – user13360436 Jun 13 '22 at 18:18
  • As I say, its been a long time since I’ve used an NSComboBox. I don’t recall what you are referring to about a `.action` option. What in particular are you referring to? – Duncan C Jun 14 '22 at 00:28
  • when creating a new button I can do the following: myButton.action = #selector(some_function(_:)), I don't get any errors when doing the same thing with a combo box, but also it doesn't trigger the function as expected – user13360436 Jun 14 '22 at 07:27
  • It looks like NSComboBox does inherit from NSControl, so it takes an action, but that doesn't appear to be how you are supposed to use it. Have your view controller conform to the `NSComboBoxDelegate` protocol, set your view controller as the delegate, and implement the `comboBoxSelectionDidChange(_:)` method. – Duncan C Jun 14 '22 at 10:25
  • If you do that your view controller's `comboBoxSelectionDidChange(_:)` method will be called when the user changes the selection. – Duncan C Jun 14 '22 at 10:26
0

here is the solution in case that anyone else run into the same issue: add to your ViewController Class 'NSComboBoxDelegate'. to your combobox creation function add 'combox.delegate = self'. add another function called func 'comboBoxSelectionDidChange(_ notification: Notification)' which will be triggered by the selection changes

class MainViewController: NSViewController, NSComboBoxDelegate
{    
  override func viewDidLoad()
  {
      super.viewDidLoad()
  }


  func populate_scroller_with_combobox(json_file: Array<Any>, panel: NSView)
  {
      let combox = NSComboBox()
      combox.identifier = NSUserInterfaceItemIdentifier(rawValue: "combobox1")
      combox.addItem(withObjectValue: "None")
      combox.addItems(withObjectValues: json_file_content)
      combox.numberOfVisibleItems = 10
      combox.isEditable = false
      combox.selectItem(withObjectValue: "None")
      combox.delegate = self
      panel.addSubview(combox)
      combox.frame = CGRect(x:190, y: 30, width: 170, height: 26)
  }

  func comboBoxSelectionDidChange(_ notification: Notification)
  {
      print("Combobox value changed.")
  }
}