The Missing Manual
for Swift Development
The Guide I Wish I Had When I Started Out
Join 20,000+ développeurs qui apprennent le développement Swift
Téléchargez votre copie gratuite
Le projet Photos utilise exclusivement des storyboards pour concevoir et créer des contrôleurs de vue. Dans cet épisode, je vous montre que le pattern coordinator n’est pas limité aux storyboards. Vous pouvez également utiliser le pattern coordinator si vous préférez les fichiers XIB aux storyboards. Si vous préférez n’utiliser ni l’un ni l’autre, c’est également possible. La façon dont vous concevez et créez les contrôleurs de vue de votre projet n’a pas d’importance.
Projet de démarrage
Le projet de démarrage de cet épisode est fonctionnellement identique au projet fini de l’épisode précédent. Il y a cependant quelques différences que je tiens à souligner. La classe TermsViewController
ne se conforme plus au protocole Storyboardable
et elle a maintenant trois sous-classes, TermsViewControllerStoryboard
, TermsViewControllerXIB
, et TermsViewControllerCode
.
La classe TermsViewControllerStoryboard
est identique à la classe TermsViewController
de l’épisode précédent. L’interface utilisateur de la classe TermsViewControllerStoryboard
est définie dans Main.storyboard. Nous pouvons instancier une instance de la classe en invoquant la méthode instantiate()
du protocole Storyboardable
.
L’interface utilisateur de la classe TermsViewControllerXIB
est définie dans TermsViewControllerXIB.xib. La classe TermsViewControllerXIB
définit une propriété statique et variable, nibName
, pour éviter l’utilisation de littéraux de chaîne. Ceci est similaire à la propriété storyboardIdentifier
définie dans Storyboardable.swift.
Comme son nom l’indique, la classe TermsViewControllerCode
n’a pas de lien avec un storyboard ou un fichier XIB. L’interface utilisateur est créée en code. Cela entraîne évidemment un peu plus de code. Jetons un coup d’œil à chacun de ces contrôleurs de vue et explorons comment ils s’intègrent dans le modèle du coordinateur.
Storyboards
Les storyboards existent depuis plusieurs années et Apple encourage les développeurs à les utiliser. J’utilise des storyboards dans la plupart des projets sur lesquels je travaille. Xcode crée automatiquement un storyboard lorsque vous créez un tout nouveau projet, mais je recommande vivement d’utiliser plusieurs storyboards plus petits plutôt qu’un seul grand storyboard. En utilisant plusieurs petits storyboards, vous pouvez éviter les conflits de fusion plus facilement et travailler avec de petits storyboards est plus rapide et moins complexe.
Les ségrégations sont une caractéristique clé des storyboards, mais je ne les utilise jamais en combinaison avec le pattern coordinateur. Bien qu’il soit possible d’utiliser des segues en combinaison avec le pattern coordinateur, une segue implique le contrôleur de vue dans le flux de l’application et c’est quelque chose que nous voulons éviter. Rappelez-vous que les coordinateurs du projet gèrent le flux d’application. Un contrôleur de vue n’a pas besoin de savoir quoi que ce soit sur le flux d’application et il n’a pas besoin de savoir sur les autres contrôleurs de vue.
Même sans segues, les storyboards ont leur valeur. Je divise toujours les projets moyens à grands en modules. Chaque module a un storyboard, qui contient les contrôleurs de vue du module.
Ouvrir TermsCoordinator.swift et naviguer jusqu’à la méthode showTerms()
. L’implémentation est identique à celle du projet fini de l’épisode précédent. La seule différence est le nom de la classe du contrôleur de vue. Le coordinateur de termes instancie la classe TermsViewControllerStoryboard
au lieu de la classe TermsViewController
.
// MARK: - Helper Methodsprivate func showTerms() { // Initialize Terms View Controller let termsViewController = TermsViewControllerStoryboard.instantiate() // Install Handlers termsViewController.didCancel = { in self?.finish() } // Present Terms View Controller presentingViewController.present(termsViewController, animated: true)}
XIBs
Les fichiers XIB existent depuis les premiers jours du développement Cocoa. Ils manquent de quelques fonctionnalités par rapport aux storyboards, mais ils ont toujours leur valeur. J’utilise principalement les XIB pour les composants réutilisables, tels que les cellules de vue de tableau et les cellules de vue de collection.
Ouvrir les termesViewControllerXIB.xib. L’interface utilisateur de la classe TermsViewControllerXIB
est identique à celle de la classe TermsViewControllerStoryboard
dans Main.storyboard. Ouvrez TermsCoordinator.swift et revisitez la méthode showTerms()
. Pour créer une instance de la classe TermsViewControllerXIB
, nous invoquons l’initialisateur init(nibName:bundle:)
, en passant le nom du fichier XIB et une référence au bundle contenant le fichier XIB.
// MARK: - Helper Methodsprivate func showTerms() { // Initialize Terms View Controller let termsViewController = TermsViewControllerXIB(nibName: TermsViewControllerXIB.nibName, bundle: .main) // Install Handlers termsViewController.didCancel = { in self?.finish() } // Present Terms View Controller presentingViewController.present(termsViewController, animated: true)}
Code
Il est également possible de créer l’interface utilisateur des contrôleurs de vue du projet en code. Si vous n’aimez pas les storyboards ou les fichiers XIB, alors c’est votre seule option. Je n’ai pas beaucoup utilisé cette option depuis l’introduction des storyboards, mais elle peut être utile de temps en temps.
Créer et initialiser un contrôleur de vue en code est utile si ce contrôleur de vue a une interface utilisateur complexe ou dynamique. Créer et initialiser des contrôleurs de vue dans le code présente un autre avantage convaincant. Cela permet l’injection d’initialisateurs, une forme d’injection de dépendances. Je discute de l’injection de dépendances dans le prochain épisode.
Pour créer une instance de la classe TermsViewControllerCode
, nous invoquons l’initialisateur init()
. Cela équivaut à invoquer l’initialisateur init(nibName:bundle:)
et à passer nil
pour les deux arguments.
// MARK: - Helper Methodsprivate func showTerms() { // Initialize Terms View Controller let termsViewController = TermsViewControllerCode() // Install Handlers termsViewController.didCancel = { in self?.finish() } // Present Terms View Controller presentingViewController.present(termsViewController, animated: true)}
Quoi d’autre ?
Le pattern coordinateur est un pattern flexible. Peu importe que vous utilisiez des storyboards, des fichiers XIB ou aucun des deux. Vous pouvez utiliser des segues, mais rappelez-vous que vous violez un principe fondamental du pattern coordinateur si vous le faites. Un contrôleur de vue n’a pas besoin de connaître le flux de l’application et il ne doit pas connaître les autres contrôleurs de vue.