Introduction à Swift UI

07/06/2019

Introduction à Swift UI

Attention, pour tester SwiftUI, il est nécessaire d’avoir installé Xcode 11 et maxOS Catalina. N’installez pas macOS Catalina comme OS principal, faites plutôt un dual boot. 
Pour rappel, il ne s’agit que de la première beta !
Qu’est-ce que Swift UI ?

SwiftUI est le nouveau framework d’Apple qui a pour vocation de simplifier grandement la conception de vues d’une application grâce à une approche assez nouvelle, mais extrêmement lisible.

Démarrage

Pour commencer, on crée un nouveau projet Xcode. La seule différence par rapport à avant (et on verra tout à l’heure pourquoi cela est nécessaire) est qu’il faut cocher la case “use Swift UI” lors de la création du projet.

– N’appelez pas votre projet “SwiftUI”, cela engendre des erreurs dans le projet !

La suite ne change pas par rapport à avant.

Une fois le projet créé, certains changements se font remarqués tels que l’apparition de deux nouveaux fichiers : “SceneDelegate.swift” et “ContentView.swift” et la disparition de “Main.storyboard” ainsi que “ViewController.swift”.

 
Prise en main

Nous nous intéresserons au SceneDelegate.swift plus tard, pour le moment, regardons le fichier “ContentView.swift”. Lorsque vous êtes sur le bon fichier, si la preview n’est pas affichée automatiquement, on peut l’afficher en allant dans Editor / Editor and Canvas (Cmd + option + retour).

À partir de là, on voit apparaitre à gauche du code et à droite une preview représentant un device. Pour changer l’apparence de ce device, il suffit de choisir un autre type de simulateur ou un device réel et la preview affichera alors le device choisi. Nous verrons par la suite à quoi servent les boutons en bas à droite de ce simulateur. Sur cette preview, il n’y a qu’un simple texte “Hello World”.

À gauche, dans la partie code, on voit deux structs :

  • ContentView
  • ContentView_Previews

C’est dans la première struct “ContentView” qu’on va écrire notre code. La deuxième struct permet d’afficher la vue que nous voulons prévisualiser. Elle n’est d’ailleurs compilée que pour le debug.

Les choses sérieuses commencent

Nous partirons sur cette base de code existante :

struct ContentView: View {
  var body: some View {
    Text("Hello World")
  }
}

Pour commencer, remplacez le “Hello World” par “Hello SwiftUI”. On constate que la preview se met à jour instantanément.

Maintenant, changeons la couleur de ce texte, pour cela on va appeler sa méthode “color(_:)” aussi simplement que :

Text("Hello SwiftUI").color(.blue)

// Pour plus de lisibilité, nous mettrons toutes les méthodes à la ligne avec une indentation standard
Texte("Hello SwiftUI")
.color(.blue)

Le texte est maintenant bleu. Si on veut customiser un peu plus ce Text(), il suffit d’ajouter les méthodes correspondantes :

Text("Hello SwiftUI")
    .color(.blue)
    .font(.largeTitle)
    .bold()

– Plutôt chouette, non ? Mais vous n’avez pas tout vu !

Nous avons vu que la preview se met à jour automatiquement, mais il est possible d’inspecter et de modifier les réglages d’un texte, ou de tout autre view, depuis la preview de manière très simple ! En faisant Cmd + clic sur l’élément à inspecter, puis en sélectionnant “Inspecter”, on ouvre un pop-up permettant de configurer notre élément graphique. Lorsque nous modifions un paramètre depuis cet inspecteur, la modification est automatiquement retranscrite dans le code (le code est d’ailleurs toujours la base de référence).

Mais le mieux dans tout cela, c’est que cet inspecteur fonctionne aussi depuis le code ! Cela aura pour effet de modifier le code et la preview !

Ajouter d’autres view

– Ok, c’est bien cool, mais avec juste un texte on ne va pas aller bien loin. Voyons maintenant comment ajouter d’autres view. Cela est encore une fois très simple, d’ailleurs avec SwiftUI c’est un peu le mot d’ordre.

Ceci étant, quelques subtilités demeurent. En effet, si vous souhaitez ajouter un nouveau texte à la suite du premier, vous allez vite vous retrouver confronté à tout un tas d’erreurs.

En effet, la propriété body de notre ContentView a été conçue pour représenter le contenu et le comportement de la vue. On ne peut donc pas y ajouter plusieurs vues. Pour cela, il existe plusieurs types de conteneurs tels que les “Group”, “List”, “Button”, “VStack”, “HStack” qui permettent de contenir plusieurs views.

– Ok, mais on utilise ça comment ??

Patience, j’y viens.

Ajouter d’autres vues

La méthode la plus simple pour le faire est d’utiliser Cmd + clic sur notre élément Text(_:) et de choisir “Embed in VStack”. Et hop, un nouveau struct VStack vient d’être ajouté dans le code.

À priori, aucuns changements dans la preview. Mais si maintenant nous ajoutons un nouveau texte, en-dessous du premier, il va apparaitre dans la preview également en-dessous du premier.

Pour ajouter des views, nous avons deux solutions :

  • Écrire le nom de la vue voulue,
  • Utiliser la librairie comme dans un storyboard (Cmd + Maj + L) et la nouvelle view s’ajoutera là où est positionné le curseur.

– Si votre preview ne se met pas à jour, il se peut qu’elle soit en pause. Pour cela cliquez sur le bouton “Resume” en haut à droite de la fenêtre de preview.

Lorsque le deuxième texte est ajouté en-dessous du premier, on voit qu’il est automatiquement ajouté à la preview en-dessous de notre “Hello SwiftUI”.

L’ajout d’un nouvel élément depuis la librairie fonctionne tout aussi bien dans la preview, tout comme la création de la VStack (qui est comme une stackView pour ceux qui ne suivraient pas).

Ajout d’autres view : suite

Super, maintenant que nous avons vu comment ajouter des vues et que vous commencez à voir et comprendre la logique de SwiftUI, nous pouvons passer à la suite.

Remplacez le deuxième bloc de texte par ceci : (ajoutez une image dans le dossier assets et remplacez “Image(“flower”) par le nom de votre image !

VStack {
Image("flower")
.clipShape(Circle())
.overlay(
Circle().stroke(Color.white, lineWidth: 4))
.shadow(radius: 10)
Text("New content text")
.color(.red)
}
.padding(10)

– Ok sympa, mais ça reste la même chose que précédemment, non ?

Oui, vous avez raison ! Pour remédier à cela, créez un nouveau fichier SwiftUI (Cmd + n / nouveau fichier SwiftUI View) et nommez-le “DescriptionView.swift”.

Ensuite, supprimez tout ce que vous venez d’ajouter dans “ContentView.swift”, sauf le premier texte et collez-le dans votre nouveau fichier “DescriptionView”.

Maintenant, retournez dans votre fichier ContentView.swift et en-dessous du texte, ajoutez juste DescriptionView().

Tada ! Merci Swift UI.

Petite astuce de la preview, il est possible d’en afficher plusieurs et surtout d’en configurer la taille comme dans le playground !

Pour cela, dans la struct “ContentView_Previews”, ajoutons la content view à un groupe (Cmd + clic sur ContentView() / Embed in Group) et ajoutons notre DescriptionView() dans ce nouveau groupe.

Re Tada ! Il y a maintenant deux previews.

– Ok, mais pourquoi faire ?

Ajoutez la méthode “.previewLayout(.fixed(width: 300, height: 300))” en-dessous de notre DescriptionView() et vous allez voir la preview prendre cette dimension.

.previewLayout(.fixed(width: 300, height: 300))

Je pense que maintenant tout le monde voit ce qu’il va pouvoir faire de cela. Pour les autres, réfléchissez ! 😉

Pour information, si vous mettez cette méthode “.previewLayout(.fixed(width: 300, height: 300))” sur le groupe, c’est tout le groupe qui va changer d’affichage ! Pour utiliser la taille du device seulement sur une vue, il suffit de remplacer “.previewLayout(.fixed())” par “.previewLayout(.device)”.

Configurer sa vue de lancement

Souvenez-vous du fichier SceneDelegate.swift, c’est le moment d’en reparler !

Il contient quelques méthodes qui permettent, un peu à la manière de l’AppDelegate, d’exécuter du code lorsqu’il y a des évènements sur nos scènes. La méthode qui nous intéresse est la première :

func scene(_ scene: UIScene, 
willConnectTo session: UISceneSession,
options connectionOptions: UIScene.ConnectionOptions)

À la ligne 24, on défini la rootView qui, par défaut, est notre ContentView() créé lors de la création du projet. C’est cette vue qui sera affichée sur notre simulateur ou sur notre device lors de l’exécution de l’app. Pour changer cela, il suffit de remplacer :

window.rootViewController = UIHostingController(rootView: ContentView())

par :

window.rootViewController = UIHostingController(rootView: DescriptionView())
Conclusion

Voilà, c’est tout pour cette courte intro à SwiftUI. J’espère que, comme moi, vous avez hâte de pouvoir l’utiliser dans vos projets !

Si cet article vous a plu, n’hésitez pas à me le faire savoir et à le partager ! J’en ferais alors probablement d’autres sur ce thème ! 😉

Nicolas • Développeur iOS Swift  Nantes

MENTIONS LÉGALES

© 2019 Nicolas Bachur. Tous droits réservés.