Передача аргументов в селектор в 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
}