Аргумент "#selector" не относится к методу "@objc", свойству или инициализатору

Я подклассифицирован в подклассе Swift 3 a UIButton, который написан в Objective-C.

Когда я пытаюсь добавить цель, она не работает с кодом ошибки:

class ActionButton: JTImageButton {

    func action() {

    }

    func configure()) {
        // ...
        self.addTarget(self, action: #selector(self.action()), for: .touchUpInside)
        // error: 
        // Argument of '#selector' does not refer to an '@objc' method, property, or initializer

    }
}

Ответ 1

Все, что вам нужно сделать, это отметить func как @objc, и нет необходимости в ссылке self или в скобках

class ActionButton: JTImageButton {

    @objc func btnAction() {

    }

    func configure() {
        // ...
        self.addTarget(self, action: #selector(btnAction), for: .touchUpInside)
        // error: 
        // Argument of '#selector' does not refer to an '@objc' method, property, or initializer

    }
}

Вы даже можете сделать это private, если хотите

Ответ 2

Проблема заключается в том, что в #selector(self.action()), self.action() - вызов метода. Вы не хотите вызывать метод; вы хотите назвать этот метод. Скажем #selector(action): потеряйте круглые скобки, а также нет необходимости в self.

Ответ 3

Добавлен из комментариев к другому ответу: func action() - это не просто плохой выбор для имени функции и действия, она не может быть создана. (Вы можете использовать его как параметр функции ввода, хотя я это делаю для ясности при передаче цели/действия в init(), который устанавливает эти вещи.) Я заменяю это на MyAction() для ясности.


Попробуйте следующее:

self.addTarget(self, action: #selector(MyAction), for: .touchUpInside)

Говорящий, гораздо лучший дизайн - это переместить функцию MyAction() в супервизор кнопки, поскольку это делает вещи более согласованными с базовым дизайном MVC:

SuperView:

let myButton = ActionButton()
// include other button setup here
myButton.addTarget(self, action: #selector(MyAction), for: .touchUpInside

func action(_ sender: ActionButton) {
    // code against button tap here
}

Альтернативное кодирование для этого, сохраняя метод "action()" в контроллере представления, но перемещая только "addTarget" в кнопку:

self.addTarget(superview?, action(superview?.MyAction), for: .touchUpInside)

Почему я прошу вас рассмотреть возможность переноса метода "MyAction()" в супервизор? Двукратное:

  • Он управляет не только кнопкой, но и всеми другими вложенными в нее представлениями, и они обычно взаимодействуют друг с другом через контроллер вида.
  • Это делает кнопку намного более многоразовой в других сценариях.

Ответ 4

Добавление ключевого слова @objc в начале метода, который является идеальным, но я все еще получил эту ошибку. Наконец, я нашел решение следующим образом введите описание изображения здесь

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

Ответ 5

Вместо того, чтобы говорить self.action(), используйте ActionButton.action().

Ответ 6

Если вы не возражаете добавить дополнительную функцию, вы можете вложить эту функцию.

self.addTarget(self, action: myAction, for: UIControlledEvent)

myAction(){
    @obj.methodYouWantToCall(//parameters//)
}