Функция вызова массива кнопок Swift MacOS с аргументом

У меня есть игровое поле для настольной игры, похожее на шахматы с 60 полями. Вместо того, чтобы соединять их вручную в раскадровке, я хочу сделать это с помощью for...in. Мой код такой:

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)

И вот такая функция (не понимаю, зачем мне @objc перед функцией, но только так она работает.

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

Код работает нормально. Но я хочу передать аргумент функции, чтобы я мог деактивировать только что нажатую кнопку, а не только [2], как в этом примере. (и я хочу добавить к этой функции другие вычисления).

Я искал вокруг, и кажется, что нельзя передавать аргументы. Если это правда, как еще я могу решить свою проблему?

РЕДАКТИРОВАТЬ: Отличный ответ и объяснение, спасибо. К сожалению, я задал вопрос неточно: я хочу не только деактивировать нажатую кнопку, но и выполнять такие вычисления:

var score = 5+/NumberOfButtonPressed/

Таким образом, если нажата первая кнопка, счет = 6, если нажата 10-я кнопка, счет = 15.


person Andy    schedule 07.01.2018    source источник


Ответы (1)


Вам нужно @objc, потому что в противном случае компилятор Swift не создаст селектор для метода. Селектор — это значение Objective-C, которое идентифицирует метод, и необходимо вызвать метод через Objective-C. (Какао написано на Objective-C.) Вы можете получить селектор метода, используя #selector, как вы уже нашли.

В macOS действия, вызываемые через Cocoa, принимают 0 или 1 дополнительный параметр. Необязательный параметр — это «отправитель», то есть объект, вызвавший действие (кнопка, на которую вы нажали). Попробуй это:

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

Вам не нужно менять выражение #selector(). Среда выполнения Cocoa вызовет ваш метод с этим параметром просто потому, что он существует.

person zneak    schedule 07.01.2018
comment
В методе target/action selector sender никогда не является необязательным, если указан параметр. - person vadian; 07.01.2018
comment
@vadian, из-за того, как параметры передаются на каждой платформе, которую поддерживает Cocoa, это необязательно. Это задокументированное поведение (см. внизу) для iOS и подразумевается для macOS (хотя, насколько мне известно, третья подпись не поддерживается). - person zneak; 07.01.2018
comment
@vadian, извините, я неправильно прочитал ваш комментарий (думал, вы сказали, что сам параметр должен присутствовать). Я на самом деле не знаю об этом. - person zneak; 07.01.2018
comment
Возможно, возникло недоразумение: параметр сам по себе является необязательным. Но если параметр указан, тип параметра не является необязательным (без вопросительного знака). - person vadian; 07.01.2018