• 30 heures
  • Moyenne

Ce cours est visible gratuitement en ligne.

course.header.alt.is_video

course.header.alt.is_certifying

J'ai tout compris !

Mis à jour le 18/06/2024

Enrichissez vos interfaces graphiques

Bien, on commence à comprendre où l'on va ! Mais pour le moment, notre application ne sert pas à grand-chose. 

Plus de vues

Le slider

(de classe UISlider) 

C'est la vue qui vous permet notamment de gérer la luminosité de votre écran. Ici, elle va laisser l'utilisateur choisir une valeur entre 0 et 99. Bien sûr, vous pouvez choisir les valeurs que vous voulez.

Le stepper

(de classe UIStepper)

Un "+" et un "-" qui incrémente ou décrémente une valeur. Valeurs comprises entre 0 et 99 également avec un pas de 1.

L'héritage dans les vues

Créer une vue qui hérite d'une autre vue vous permet de les personnaliser. Par exemple, vous voulez créer une application qui contient plusieurs boutons, et vous voulez que chacun de ces boutons aient une bordure rouge, des coins arrondis et une police rouge également.

Créons une classeBoutonArrondi. Pour ça, on crée un nouveau fichier BoutonArrondi.swift, on importe le UIKit pour utiliser les éléments graphiques et on crée la classe :

class BoutonArrondi: UIButton {

    //Intialiseur
    required init?(coder aDecoder: NSCoder) {
        //Initialiseur de la classe parente
        super.init(coder: aDecoder)

        //Coins arrondis
        layer.cornerRadius = 5

        //Couleur de la bordure
        layer.borderColor = UIColor.redColor().CGColor

        //Epaisseur de la bordure
        layer.borderWidth = 2

        //Couleur du texte
        setTitleColor(UIColor.redColor(), forState: .Normal)

        //Padding a gauche et a droite
        contentEdgeInsets = UIEdgeInsets(top: 10, left: 20, bottom: 10, right: 20)
        
    }
}

Petite différence avec Swift 3 sur ces deux lignes :

//Couleur de la bordure
layer.borderColor = UIColor.red.cgColor
//Couleur du texte
setTitleColor(UIColor.red, for: .normal)

 

On se rend ensuite dans le storyboard, on sélectionne le bouton et on clique sur le 3e onglet., vous commencez à connaître. ;) Au lieu de laisser la classe prédéfinieUIButton, on écritBoutonArrondi, on appuie sur Entrée , et voilà vous pouvez personnaliser votre bouton depuis la classe BoutonArrondi !

Vous remarquerez qu'il n'y a pas de changement visuel depuis le storyboard mais rassurez-vous, le bouton sera bien rouge avec des coins arrondis. :)

Les gesture recognizers

Littéralement, ce sont des reconnaisseurs de gestes. Il existe plusieurs gesture recognizers déjà implémentés pour nous. Ils permettent de reconnaître :

  • un simple toucher,

  • un zoom avec 2 doigts,

  • une rotation avec deux doigts,

  • un mouvement linéaire rapide (swipe),

  • un glisser-déposer,

  • un mouvement partant du bord de l'écran vers le milieu,

  • et enfin un toucher long.

Ici je vais vous montrer le toucher long et le glisser-déposer.

On va ajouter un reconnaisseur de clic long sur le slider. Dans un premier temps, on va créer la méthode qui sera appelée lors du clic long :

func longClicSurSlider(sender : UILongPressGestureRecognizer) {
    alert("Clic long repéré", message: "Faire un long press sur un slider ne sert à rien.")
}

Et dansviewDidLoad:

slValue.addGestureRecognizer(UILongPressGestureRecognizer(target: self, action: #selector(longClicSurSlider)))

Mmmmmh c'est pas très clair tout ça. On va le décomposer en étapes :

//Déclaration du selecteur pour que le gesture recognizer puisse l'appeler
let slLongPress = #selector(longClicSurSlider)

//On dit que la méthode appelée est dans self et le sélecteur est slLongPress
let gestLongPress = UILongPressGestureRecognizer(target: self, action: slLongPress)

//On attribue le gesture recognizer au slider
slValue.addGestureRecognizer(gestLongPress)

On peut aussi personnaliser nos gesture recognizers :

//Meme si mon doigt bouge beaucoup, le geste sera reconnu
gestLongPress.allowableMovement = 200

//Mon geste sera reconnu s'il y a au moins 2 doigts
gestLongPress.numberOfTouchesRequired = 2

Voilà pour le long press. Passons au glisser-déposer. On va essayer de déplacer le stepper.

DansviewDidLoad(exactement comme pour le long press) :

stepperValue.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(glisserDeposerStepper)))

On crée donc la méthodeglisserDeposerStepper:

func glisserDeposerStepper(sender : UIPanGestureRecognizer) {
    //On récupère la vue à laquelle est attachée le gesture recognizer
    let step = sender.view!

    //On récupère la position du doigt sur l'ecran
    let coordonneesDuToucher = sender.locationInView(self.view)

    //On déplace la vue récupéré en plaçant son centre au niveau du doigt
    step.center = coordonneesDuToucher
}

Ici on choisit de déplacer une vue par son centre. C'est plus logique quand on y pense.

Le centre d'une vue est de typeCGPointet plus précisément défini par une coordonnée x et une coordonnée y. La coordonnée x représente la distance du centre de la vue par rapport au bord gauche du controller et la coordonnée y par rapport au haut du controller.

On peut également déplacer la vue par son origine qui est également de typeCGPoint. On aurait pu écrirestep.frame.origin = coordonneesDuToucher. Essayez, et cherchez la différence.

On peut également personnaliser le glisser-déposer (avec le nombre de doigts nécessaires par exemple). Mais surtout, on peut savoir si le glisser déposer commence, est en cours de mouvement, ou se termine.

Et c'est vous qui allez mettre ça en pratique à travers votre prochaine activité !‌

 

Info (plus ou moins) pratique : vous pouvez également utiliser le storyboard pour créer des gesture recognizers, c'est juste moins pratique. Voici la marche à suivre : 

Solutions des défis

Solution du défi n°1

Ajoutez les variables :

@IBOutlet var slValue: UISlider!
@IBOutlet var stepperValue: UIStepper!

Liez-les au storyboard. Puis implémentez les fonctions suivantes :

//Dès que le texte est modifié, je mets à jour les valeurs des autres éléments
@IBAction func texteModifie (sender : UITextField) {
    //Si le contenu existe
    if let resultat = sender.text {
        //Si le contenu est convertible en entier
        if let entier = Int(resultat) {
            //On ne doit pas pouvoir aller au-delà de 99
            if entier > 99 { 
                sender.text = "99"
            }

            //On met à jour les valeurs des autres éléments
            slValue.setValue(Float(entier), animated: true)
            stepperValue.value = Double(entier)
        }
    }
}

//Dès que le slider change
@IBAction func sliderMove(sender : UISlider) { 
    let entier = Int(sender.value)
    tfNombreEntre.text = "\(entier)"
    stepperValue.value = Double(entier)
}

//Dès que le stepper change
@IBAction func stepperTouched(sender : UIStepper) { 
    let entier = Int(sender.value)
    tfNombreEntre.text = "\(entier)"
    slValue.value = Float(entier)
}

Liez les fonctions au storyboard : pour le slider (value changed) et pour le stepper (value changed)

var coordonneeARetenir : CGPoint!
var xDebutDeplacement : CGFloat!
Exemple de certificat de réussite
Exemple de certificat de réussite