Notre application commence à prendre une bonne forme ! Nous pouvons maintenant lancer une nouvelle partie en chargeant de nouvelles questions. Mais nous ne pouvons pas y répondre. Donc le jeu est pour l'instant assez limité... Pour répondre aux questions, l'utilisateur va devoir glisser la question à gauche ou à droite :
Si l'utilisateur pense que la question est vraie, il la glisse vers la droite et inversement. Dans ce chapitre, nous allons donc apprendre à interpréter les gestes de l'utilisateur.
A la découverte de UIGestureRecognizer
Il y a deux classes qui permettent de gérer les gestes de l'utilisateur sur l'écran tactile :
UIGestureRecognizer
: pour les gestes simplesUITouch
: pour des interprétations plus fines des gestes.
On fait déjà énormément de choses avec UIGestureRecognizer
donc je n'aborderais pas UITouch
dans ce cours.
Quand utiliser UIGestureRecognizer ?
Mais je sais déjà interpréter les gestes ?
Ah bon... ?
Mais oui ! On vient de voir avec les actions que je peux répondre à l'appui sur le bouton !
Bien vu ! Tous les composants par défaut que je vous ai présentés ont pour la plupart des gestes prédéfinis. Donc pour ceux-là, vous n'aurez pas besoin de UIGestureRecognizer
.
Pour tous les autres cas, vous en aurez besoin !
Les sous-classes de UIGestureRecognizer
En fait, on ne va pas utiliser UIGestureRecognizer
directement, mais ses sous-classes. Ces sous-classes définissent chacune un geste simple.
Pour ceux qui ne peuvent pas, voici un tableau qui donne les sous-classes principales de UIGestureRecognizer
:
Dans ce cours, nous allons utiliser UIPanGestureRecognizer
pour faire glisser notre vue à droite ou à gauche.
Utiliser un UIGestureRecognizer
Comme tout ce qui concerne l'interface, il y a deux moyens de créer un UIGestureRecognizer
:
Avec le code
Avec le storyboard
Pour changer, je vais vous montrer ça dans le code. Et comme je suis sympa, j'ai fait pour vous cette vidéo pour vous montrer comment on fait ça dans le storyboard !
Créer un UIGestureRecognizer
On veut que le geste soit détectable le plus tôt possible, dès que l'interface est chargée. Donc nous allons créer notre geste dans viewDidLoad
.
UIGestureRecognizer
a besoin de trois informations pour fonctionner :
Target : Qui est responsable de gérer le geste ? En général le contrôleur.
Action : Quelle action doit-on effectuer quand le geste est reconnu ?
View : Quelle vue doit détecter le geste ?
UIGestureRecognizer
et ses sous-classes ont un initialiseur qui réclame les deux premiers paramètres :
let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(dragQuestionView(_:)))
Détaillons tout ça :
Pour le paramètre
target
, je choisis doncself
pour faire référence au contrôleur.Pour le paramètre
action
, comme dans le chapitre précédent, j'utilise un sélecteur dans lequel je passe la méthodedragQuestionView
que je crée par ailleurs comme ceci :
func dragQuestionView(_ sender: UIPanGestureRecognizer) {
}
J'ai donné à cette méthode le paramètre sender
qui est notre UIPanGestureRecognizer
.
Il nous faut maintenant préciser la vue qui doit détecter le geste. Pour cela, on utilise la méthode addGestureRecognizer
de UIView
.
let panGestureRecognizer = UIPanGestureRecognizer(target: self, action: #selector(dragQuestionView(_:)))
questionView.addGestureRecognizer(panGestureRecognizer)
Et voilà notre geste est reconnu ! Il nous faut maintenant implémenter la méthode dragQuestionView
!
Les états des gestes
UIGestureRecognizer
a une propriété state
qui décrit l'état du geste. Elle va nous être utile pour savoir où en est le geste. Cette propriété est de type UIGestureRecognizerState
qui est une énumération qui a donc plusieurs cas :
possible
: C'est le cas par défaut. Le gesture recognizer attend de détecter un geste.began
: Le gesture recognizer vient de détecter le geste.changed
: La valeur vient de changer et le geste se poursuit.ended
: Le geste est terminé, l'utilisateur a lâché l'écran.cancelled
: Un autre geste vient interrompre le geste en cours.
Voici ce que nous allons faire :
Lorsque le geste est en cours (
began
etchanged
), nous allons modifier la position de notre vue question pour qu'elle suive le doigt.Lorsque le geste est terminé (
cancelled
etended
), nous allons enregistrer la réponse choisie par l'utilisateur et proposer la question suivante.
Et comme nous avons à faire à une énumération, nous allons utiliser un switch
:
switch sender.state {
case .began, .changed:
// La vue doit suivre le doigt
case .ended, .cancelled:
// On enregistre la réponse choisie
default:
break
}
Pour ne pas surcharger ce switch
, nous allons créer deux méthodes que nous allons remplir dans le prochain chapitre :
func dragQuestionView(_ sender: UIPanGestureRecognizer) {
switch sender.state {
case .began, .changed:
transformQuestionViewWith(gesture: sender)
case .ended, .cancelled:
answerQuestion()
default:
break
}
}
private func transformQuestionViewWith(gesture: UIPanGestureRecognizer) {
}
private func answerQuestion() {
}
Il ne nous reste qu'une toute petite chose à faire ici. Nous voulons que l'utilisateur puisse déplacer la vue question uniquement lorsque le jeu est en cours ! Pour cela, nous allons vérifier que la propriété state
de game
est à la valeur ongoing
.
func dragQuestionView(_ sender: UIPanGestureRecognizer) {
if game.state == .ongoing {
switch sender.state {
case .began, .changed:
transformQuestionViewWith(gesture: sender)
case .ended, .cancelled:
answerQuestion()
default:
break
}
}
}
Et voilà ! Notre geste est prêt à être interprété ! La suite, au prochain épisode !
En résumé
Il existe deux classes pour gérer les gestes en iOS
UITouch
etUIGestureRecognizer
.UIGestureRecognizer
et ses sous-classes permettent facilement de rajouter des gestes classiques à une interface.Pour créer un
UIGestureRecognizer
, on doit lui donner une cible (le contrôleur le plus souvent), la vue qui reçoit le geste et l'action à effectuer quand le geste est reconnu.UIGestureRecognizer
a une propriétéstate
qui permet de savoir où en est le geste.