1

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.

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

4 Comments

In a target / action selector method the sender is never optional if the parameter is specified.
@vadian, due to how parameters are passed on every platform that Cocoa supports, it is optional. This is documented behavior (see bottom) for iOS, and implied to be true for macOS (although, AFAIK, the third signature is not supported).
@vadian, sorry, I misread your comment (thought you said that the parameter itself has to be present). I don't actually know about that.
There might be a misunderstanding: The parameter per se is optional. But if the parameter is specified, the type of the parameter is non-optional (without question mark).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.