Search code examples
arraysswiftnsbutton

Swift MacOS array of buttons call function with argument


I have a playing field for a board game similar to chess with 60 fields. Instead of connecting them manually in storyboard I want to do it with a for...in. My code is like this:

let feld = NSButton()
feld.frame = CGRect(x: 1300+30*h, y: 20, width: 22, height: 22)
feld.target = self
feld.action = #selector(ButtonTest)
self.view.addSubview(feld)
ButtonArray.append(feld)

And the function like this (I dont understand why I need @objc before the function but only this way it works.

@objc func ButtonTest() {
ButtonArray[2].isEnabled=false
}

The code work fine. But I want to pass an argument to the function so I can deactivate the button just being pressed and not only [2] like in this example. (and I want to add other calculations to this function).

I searched around and it seems that one cannot pass arguments. If that is true how else can I solve my problem?

EDIT: Great answer and explanation, thanks. I sadly asked the question imprecisely: I dont only want to deactivate the pressed button but also do calculations like this:

var score = 5+/NumberOfButtonPressed/

So if the first button is pressed var score=6, if the 10th button is pressed score=15.


Solution

  • You need @objc because otherwise, the Swift compiler will not create a selector for the method. A selector is an Objective-C value that identifies a method, and it is necessary to call a method through Objective-C. (Cocoa is written in Objective-C.) You can get a method's selector using #selector, as you have already found.

    On macOS, actions called through Cocoa take 0 or 1 additional parameters. The optional parameter is the "sender", which is the object that triggered the action (the button on which you clicked). Try this:

    @objc
    func ButtonTest(sender: NSButton?) {
        sender?.isEnabled = false
    }
    

    You don't need to change the #selector() expression. The Cocoa runtime will call your method with that parameter just by virtue of it existing.