Передача аргументов в селектор в Swift

Я программно добавляю UITapGestureRecognizer к одному из своих представлений:

let gesture = UITapGestureRecognizer(target: self, action: #selector(self.handleTap(modelObj:myModelObj)))

self.imageView.addGestureRecognizer(gesture)

func handleTap(modelObj: Model) {
  // Doing stuff with model object here
}

Первая проблема, с которой я столкнулся, - "Аргумент" #selector "не относится к методу, свойству или инициализатору" @Objc ".

Прохладный, поэтому я добавил @objc в подпись handleTap:

@objc func handleTap(modelObj: Model) {
  // Doing stuff with model object here
}

Теперь я получаю сообщение об ошибке "Метод не может быть помечен как @objc, потому что тип параметра не может быть представлен в Objective-C.

Это просто изображение карты здания, с некоторыми изображениями, указывающими расположение точек интереса. Когда пользователь удаляет один из этих контактов, я хотел бы знать, какую точку интереса они использовали, и у меня есть модельный объект, который описывает эти точки интереса. Я использую этот объект модели, чтобы дать его координату на карте, поэтому я подумал, что было бы легко просто отправить объект обработчику жестов.

Ответ 1

Похоже, вы неправильно понимаете несколько вещей.

При использовании target/action подпись функции должна иметь определенную форму…

func doSomething(sender: Any)

или

func doSomething(sender: Any, forEvent event: UIEvent)

где...

Параметр sender является объектом управления, отправляющим сообщение действия.

В вашем случае отправителем является UITapGestureRecognizer

Кроме того, #selector() должен содержать подпись func, и НЕ включает передаваемые параметры. Так что...

func handleTap(sender: UIGestureRecognizer) {

}

вы должны иметь...

let gesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(sender:)))

Предполагая, что функция и жест находятся в контроллере представления, для которого modelObj является свойством /ivar, нет необходимости передавать его с помощью распознавателя жестов, вы можете просто обратиться к нему в handleTap

Ответ 2

Шаг 1. Создайте пользовательский объект отправителя.

шаг 2: добавьте свойства, которые вы хотите изменить, чтобы пользовательский объект отправителя

шаг 3: введите отправителя при получении функции в пользовательский объект и получите доступ к этим свойствам

Например: при нажатии на кнопку, если вы хотите отправить строку или любой другой объект, то

Шаг 1: создать

class CustomButton : UIButton {

    var name : String = ""
    var customObject : Any? = nil
    var customObject2 : Any? = nil

    convenience init(name: String, object: Any) {
        self.init()
        self.name = name
        self.customObject = object
    }
}

шаг 2-а: установить собственный класс в раскадровке

enter image description here

Шаг 2-б. Создайте IBOutlet для этой кнопки с пользовательским классом следующим образом

@IBOutlet weak var btnFullRemote: CustomButton!

шаг 3: добавьте свойства, которые вы хотите изменить, чтобы пользовательский объект отправителя

btnFullRemote.name = "Nik"
btnFullRemote.customObject = customObject
btnFullRemote.customObject2 = customObject2
btnFullRemote.addTarget(self, action: #selector(self.btnFullRemote(_:)), for: .touchUpInside)

шаг 4: приведите отправителя при получении функции к пользовательскому объекту и получите доступ к этим свойствам

@objc public func btnFullRemote(_ sender: Any) {

var name : String = (sender as! CustomButton).name as? String

var customObject : customObject = (sender as! CustomButton).customObject as? customObject

var customObject2 : customObject2 = (sender as! CustomButton).customObject2 as? customObject2

}

Ответ 3

Я думаю, вы должны создать метод @objc, который вызывает handleTap(modelObj:myModelObj).

@objc func someMethod() { // name this properly!
    handleTap(modelObj: myModelObj)
}

Затем вы можете передать это как селектор:

#selector(someMethod)

Ответ 4

Вместо того, чтобы пытаться вызвать handleTap прямо следующим образом:

 #selector(self.handleTap(modelObj:myModelObj))

Вы можете создать функцию, затем вызвать другую функцию с параметрами

#selector(anyName)

func anyName() {
    let model = Model()
    handleTap(modelObj: model)
}

func handleTap(modelObj: Model) {
    // Doing stuff with model object here
}