web-dev-qa-db-fra.com

La programmation d'un bouton UIB ne fonctionne pas dans Swift 4 Xcode 9 Beta 6, impossible d'ajouter une cible

Dans le passé, je n'ai eu aucun problème à créer un UIButton par programme, mais depuis que j'utilise Xcode 9 et Swift 4, je ne trouve pas de moyen de faire disparaître cette erreur.

//Adding target to UIButton
func PositionStartButton(xOffset: Float){
    StartButton.frame = CGRect(x: Int(0 - 40 + xOffset), y: 0, width: 80, height: 80)
    StartButton.setImage(#imageLiteral(resourceName: "Logo_Final_WHITE_Face"), for: .normal)
    StartButton.addTarget(self, action: "pressButton:", for: .touchUpInside)
    ScrollView.addSubview(StartButton)

}

//The target function
func pressButton(_ sender: UIButton){
    print("\(sender)")
}

Message d'erreur: 'NSInvalidArgumentException', raison: '- [Playing.MainMenuViewController pressButton:]: sélecteur non reconnu envoyé à l'instance 0x10440a6b0'

12
Olivier

Deux points.

Tout d'abord, depuis Swift 2.2 (fourni avec Xcode 7.3, sorti il ​​y a plus d'un an), la notation de sélecteur recommandée est #selector(...). En utilisant la notation, vous pouvez devenir plus utile messages de diagnostic, que d'utiliser une autre notation.

(Vous ne devez ignorer aucun avertissement affiché avec les paramètres recommandés.)

Seconde, dans Swift 4, vous devez annoter explicitement les méthodes invoquées via le sélecteur avec @objc. (Dans des cas très limités, Swift applique implicitement la notation, mais pas beaucoup.)

Ainsi, votre code affiché devrait être:

//Adding target to UIButton
func PositionStartButton(xOffset: Float){
    StartButton.frame = CGRect(x: Int(0 - 40 + xOffset), y: 0, width: 80, height: 80)
    StartButton.setImage(#imageLiteral(resourceName: "Logo_Final_WHITE_Face"), for: .normal)
    StartButton.addTarget(self, action: #selector(self.pressButton(_:)), for: .touchUpInside) //<- use `#selector(...)`
    ScrollView.addSubview(StartButton)

}

//The target function
@objc func pressButton(_ sender: UIButton){ //<- needs `@objc`
    print("\(sender)")
}

Ce n'est pas critique, mais vous devriez mieux suivre une règle de codage simple de Swift - seuls les noms de type sont en majuscule.

Renommez mieux vos PositionStartButton, StartButton et ScrollView, si vous pensez que vous pouvez avoir une autre chance de montrer votre code publiquement.

21
OOPer
// Add Target   

 buttonName.addTarget(self, action: #selector(ViewController.handleButton(_:)), for: .touchUpInside)

    // Handle Action

        @objc func handleButton(_ sender: AnyObject) {


    }
1
Hitesh Chauhan