web-dev-qa-db-fra.com

Passer des arguments au sélecteur dans Swift

J'ajoute par programme un UITapGestureRecognizer à l'un de mes points de vue:

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
}

Le premier problème que j'ai rencontré était "L'argument de '#selector' ne fait pas référence à une méthode, une propriété ou un initialiseur '@Objc'.

Cool, alors j'ai ajouté @objc à la signature de handleTap:

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

J'obtiens maintenant l'erreur "La méthode ne peut pas être marquée @objc car le type du paramètre ne peut pas être représenté dans Objective-C.

C'est juste une image de la carte d'un bâtiment, avec quelques images d'épingles indiquant l'emplacement des points d'intérêt. Lorsque l'utilisateur appuie sur l'une de ces broches, j'aimerais savoir quel point d'intérêt il a tapé et j'ai un objet modèle qui décrit ces points d'intérêt. J'utilise cet objet modèle pour donner à l'image de l'épingle ses coordonnées sur la carte; j'ai donc pensé qu'il aurait été facile pour moi d'envoyer l'objet au gestionnaire de gestes.

48
mike

On dirait que vous comprenez mal certaines choses.

Lors de l'utilisation de cible/action , la signature de la fonction doit avoir une certaine forme…

func doSomething(sender: Any)

ou

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

où…

Le paramètre sender est l'objet de contrôle qui envoie le message d'action.

Dans votre cas, l'expéditeur est le UITapGestureRecognizer

De plus, #selector() devrait contenir la signature func et n'inclut PAS les paramètres passés. Donc pour…

func handleTap(sender: UIGestureRecognizer) {

}

tu aurais dû…

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

En supposant que la fonction et le geste se trouvent dans un contrôleur de vue, dont modelObj est une propriété/ivar, il n'est pas nécessaire de le transmettre avec le programme de reconnaissance de geste, vous pouvez simplement vous y reporter dans handleTap

62
Ashley Mills

Étape 1: créez l'objet personnalisé de l'expéditeur.

étape 2: ajoutez les propriétés que vous souhaitez modifier dans cet objet personnalisé de l'expéditeur

étape 3: transtypez l'expéditeur dans la fonction de réception en un objet personnalisé et accédez à ces propriétés

Par exemple: en cliquant sur le bouton si vous souhaitez envoyer la chaîne ou un objet personnalisé, puis

étape 1: créer

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
    }
}

étape 2-a: Créez IBOutlet de ce bouton avec une classe personnalisée comme suit

@IBOutlet weak var btnFullRemote: CustomButton!

étape 2-b: définir la classe personnalisée dans le storyboard également

enter image description here

étape 3: ajoutez les propriétés que vous souhaitez modifier dans cet objet personnalisé de l'expéditeur

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

étape 4: transtypez l'expéditeur dans la fonction de réception en un objet personnalisé et accédez à ces propriétés

@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

}
16
Ninad Kambli