[Résolu] Méthode générique pour UIButton

busterTheobusterTheo Membre
octobre 2015 modifié dans API UIKit #1

Bonjour,


je configure plein de champs en code, et donc plutôt que de répéter plusieurs fois les même commandes de configuration du champ, j'ai fait une fonction.


 


J'essaie de faire pareil pour des boutons, et là , ça se complique, dixit l'action avec plusieurs paramètres.


 


Le code pour les champs :



override func viewDidLoad() {
super.viewDidLoad()

confFields()
}


func confFields() {
confFieldsFunction(nomTextField)
confFieldsFunction(prenomTextField)
confFieldsFunction(dateCreationTextField)
confFieldsFunction(yeuxTextField)
confFieldsFunction(ageTextField)
}

func confFieldsFunction(leChamp: UITextField) {
leChamp.layer.cornerRadius = 5.0
leChamp.layer.borderWidth = 1
leChamp.layer.borderColor = BorderChampsColor
leChamp.attributedPlaceholder = NSAttributedString(string:leChamp.placeholder!,attributes: [NSForegroundColorAttributeName: FontColor])
}

Pour les bouton, ce sont des boutons sur lesquels, lorsque l'on clique, un petit popUp (pas un popOver Apple mais une UIView custom - class PopUpField: UIView { ....... }  ) apparaà®t, et on choisit dans un des 2, ou 3, ou 4 labels du popUp.


 


Avant la tentative de création de la fonction pour éviter des dizaines de lignes de code recopiées, cela fonctionnait à  merveille.


 


Voici donc ma tentative infructueuse (sur le modèle des champs - plus haut) :


Donc, évidemment avec un (confButtons()) dans le (viewDidLoad).


 


Je ne met le code que pour un bouton, pour ne pas surcharger.



func confButtons() {
labelsSexe = ["Masculin", "Féminin"]
popUpFieldSexe = PopUpField(frame: CGRectMake(boutonSexe.frame.origin.x + 60, boutonSexe.frame.origin.y - 33, 200, 110))
confButtonsFunction(boutonSexe, unPopUpField: popUpFieldSexe)
}


func confButtonsFunction(buttonEtape: UIButton, unPopUpField: PopUpField) {
buttonEtape.contentHorizontalAlignment = UIControlContentHorizontalAlignment.Left
buttonEtape.contentEdgeInsets = UIEdgeInsetsMake(0.0, 6.0, 0.0, 0.0)
buttonEtape.addTarget(self, action: "tapButton:unPopUpField:", forControlEvents: UIControlEvents.TouchUpInside)
buttonEtape.layer.cornerRadius = 5.0
buttonEtape.layer.borderWidth = 1
buttonEtape.layer.borderColor = BorderChampsColor
}


func tapButton(button: UIButton, unPopUpField: PopUpField) {
removePopUpFieldsEtape0()
unPopUpField.backgroundColor = UIColor.clearColor()
unPopUpField.nbreLabels = 2
viewMereEtape0.addSubview(unPopUpField)

configLabelsPopUpSexe()
}


func removePopUpFieldsEtape0() {
if popUpFieldSexe != nil {
popUpFieldSexe.removeFromSuperview()
label1Sexe.removeFromSuperview()
label2Sexe.removeFromSuperview()
}
}

Ben voilà , j'ai toujours "fatal error: unexpectedly found nil while unwrapping an Optional value"


 


J'ai vu pour le selector des trucs sympas que j'ai essayé ici.


 


 


En fait je galère.


 


Si quelqu'un a une idée, ce serait super.


 


Sans quoi, c'est pas grave, je répète mes lignes de code de configuration, mais ça fait pas très pro.


 


Merci d'avance.


Réponses

  • colas_colas_ Membre
    octobre 2015 modifié #2

    Est-ce que tu utilises le point d'arrêt automatique (exception breakpoint) du debugger, qui t'amène à  la ligne où a lieu l'erreur ?


  • Merci colas_ pour ta réponse.


     


    Oui, et il s'agit de (label1Sexe.removeFromSuperview()), mais je me suis mal exprimé dans mon post, parce que ça c'est pas grave, encore une histoire de nil et avec un "if let...", je devrais m'en sortir là -dessus.


     


    Par contre, en mettant



    removePopUpFieldsEtape0() 

     en commentaires dans 



    func tapButton(button: UIButton, unPopUpField: PopUpField) {
    ...
    }

    j'ai le message d'erreur qui m'intéresse d'avantage. En fait, l'idée est que j'envoi deux paramètres à  tapButton(), qui a besoin de récupérer le bouton cliqué (ça c'est ok) mais aussi le popUpField. C'est pourquoi, j'ai le truc avec la syntaxe des deux points, dans l'action.



    buttonEtape.addTarget(self, action: "tapButton:unPopUpField:", forControlEvents: UIControlEvents.TouchUpInside)

    Et j'ai donc le message d'erreur suivant, sur la ligne



    unPopUpField.backgroundColor = UIColor.clearColor()


     


    [UITouchesEvent setBackgroundColor:]: unrecognized selector sent to instance 0x7fa2c8d39c50



     


    Pas facile ces notions de selector...


  • Joanna CarterJoanna Carter Membre, Modérateur
    octobre 2015 modifié #4
    On ne peut pas utiliser n'importe quoi comme paramètres. Le deuxième paramètre est fourni par la sytème, de type UITouchesEvent, d'où vient le message d'erreur.


    Si tu utilisais Xcode pour connecter l'action au bouton, tu aurai vu les options.
  • busterTheobusterTheo Membre
    octobre 2015 modifié #5

    Merci Joanna Carter.


     


    Oui, j'ai vu ça dans des println, et je suis donc passé sur une autre technique, en mettant un tag sur chacun de mes boutons.


     


    Voilà  où j'en suis, je suis assez content d'avoir simplifié et économisé un paquet de lignes de code.


    Et ça marche nickel.


     


    Y'a juste un truc qui me chiffonne, c'est d'avoir été obligé de créer mes popUpFields avant de cliquer sur les boutons sensés les montrer. Mais je pense que ce n'est pas très grave.


     


    Je vais mettre résolu, et je met mon petit bout de code si ça intéresse quelqu'un, même si je pense que ce n'est pas très intéressant.


    J'ai créer des tableaux, ...



    func confButtons() {
    labelsSexe = ["Masculin", "Féminin"]
    labelsTeint = ["Clair", "Mate", "Rose"]
    labelsPhysique = ["Fort", "Moyen", "Mince", "Athlétique"]
    labelsPersonnalite = ["Introverti", "Moyen", "Extraverti"]
    labelsChanger = ["La teinte des dents", "La hauteur des dents", "La forme des dents", "L'alignement des dents"]
    labelsType = ["Naturel", "Aspect télé", "Confiance au dentiste", "Conserver son apparence"]

    labelsPopUpFields = [labelsSexe, labelsTeint, labelsPhysique, labelsPersonnalite, labelsChanger, labelsType]

    popUpFieldSexe = PopUpField(frame: CGRectMake(boutonSexe.frame.origin.x + 60, boutonSexe.frame.origin.y - 33, 200, 110))
    popUpFieldTeint = PopUpField(frame: CGRectMake(boutonTeint.frame.origin.x + 60, boutonTeint.frame.origin.y - 33, 200, 110))
    popUpFieldPhysique = PopUpField(frame: CGRectMake(boutonPhysique.frame.origin.x + 60, boutonPhysique.frame.origin.y - 33, 200, 110))
    popUpFieldPersonnalite = PopUpField(frame: CGRectMake(boutonPersonnalite.frame.origin.x + 60, boutonPersonnalite.frame.origin.y - 33, 200, 110))
    popUpFieldChanger = PopUpField(frame: CGRectMake(boutonChanger.frame.origin.x + 60, boutonChanger.frame.origin.y - 33, 200, 110))
    popUpFieldType = PopUpField(frame: CGRectMake(boutonType.frame.origin.x + 60, boutonType.frame.origin.y - 33, 230, 110))

    popUpFields = [popUpFieldSexe, popUpFieldTeint, popUpFieldPhysique, popUpFieldPersonnalite, popUpFieldChanger, popUpFieldType]

    confButtonsFunction(boutonSexe)
    confButtonsFunction(boutonTeint)
    confButtonsFunction(boutonPhysique)
    confButtonsFunction(boutonPersonnalite)
    confButtonsFunction(boutonChanger)
    confButtonsFunction(boutonType)
    }

    func confButtonsFunction(buttonEtape: UIButton) {
    buttonEtape.contentHorizontalAlignment = UIControlContentHorizontalAlignment.Left
    buttonEtape.contentEdgeInsets = UIEdgeInsetsMake(0.0, 6.0, 0.0, 0.0)
    buttonEtape.addTarget(self, action: "tapButton:", forControlEvents: UIControlEvents.TouchUpInside)
    buttonEtape.layer.cornerRadius = 5.0
    buttonEtape.layer.borderWidth = 1
    buttonEtape.layer.borderColor = BorderChampsColor
    }

    func tapButton(button: UIButton) {
    removePopUpFieldsEtape0()
    let unPopUpField = popUpFields[button.tag - 1]
    unPopUpField.nbreLabels = labelsPopUpFields[button.tag - 1].count
    unPopUpField.backgroundColor = UIColor.clearColor()
    viewMereEtape0.addSubview(unPopUpField)
    configLabelsPopUpFields(button.tag)
    }


    func configLabelsPopUpFields(tagButton: Int) {
    switch(tagButton) {
    case 1:

    etc
    }

    }

    Merci à  vous pour l'aide.    :p


Connectez-vous ou Inscrivez-vous pour répondre.