Les formulaires sont une étape incontournable du développement web et mobile. Pour enregistrer des données ou mettre à jour les préférences de tes utilisateurs, tu vas forcément les utiliser un jour ou l’autre.

SwiftUI applique un style adapté aux différentes tailles d’écran et plateformes sur lesquelles tu développes (watchOS, iOS, macOS, etc). Mais ces styles peuvent être spécifiques à une plateforme. Par exemple, les formulaires apparaissent sous forme de listes groupées sur iOS, et sous forme de piles verticales alignées sur macOS.

Nous allons donc voir les différents éléments qui composent un formulaire, ainsi que des exemples pour que tu puisses toi aussi t’y mettre.

Les différents éléments d’un formulaire en SwiftUI

Élément de formulaireDescription
TextFieldPermet à l’utilisateur de saisir du texte
SecureFieldPermet à l’utilisateur de saisir du texte masqué, comme un mot de passe
TogglePermet à l’utilisateur de basculer entre deux états, comme activer ou désactiver une fonctionnalité
StepperPermet à l’utilisateur d’ajuster une valeur numérique en augmentant ou en diminuant sa valeur par pas
SliderPermet à l’utilisateur de sélectionner une valeur numérique dans une plage donnée en faisant glisser un curseur
PickerPermet à l’utilisateur de sélectionner une valeur dans une liste de choix
DatePickerPermet à l’utilisateur de sélectionner une date à partir d’un calendrier

Créer un formulaire simple

Afin de te familiariser avec les différents éléments qui composent le formulaire, nous allons commencer par créer un formulaire simple en utilisant la structure Form.

Dans cet exemple, nous allons créer un formulaire simple qui utilise un champ nom grâce à l’élément TextField, ainsi qu’un champ âge créé grâce à Stepper.

L’élément navigationTitle permet simple de jouer le rôle de label pour notre formulaire.

struct FormView: View {
    @State private var name: String = ""
    @State private var age: Int = 0
    
    var body: some View {
        Form {
            TextField("Nom", text: $name)
            Stepper("Age : \(age)", value: $age, in: 0...120)
        }
        .navigationTitle("Mon formulaire")
    }
}
Illustration de l'exemple du formulaire

Personnaliser le formulaire

Customisons à présent notre formulaire. Dans cet exemple, nous allons étudier l’utilisation de Toggle, DatePicker et Picker.

struct FormView: View {
    @State private var newsletter: Bool = false
    @State private var statutSelected = "Particulier"
    @State private var dateOfBirth: Date = Date()
    
    let statut = ["Particulier", "Professionnel"]
    
    var body: some View {
        Form {
            Section(header: Text("Informations personnelles")) {
                Toggle("Abonnement à la newsletter", isOn: $newsletter)
                DatePicker("Date de naissance", selection: $dateOfBirth, displayedComponents: .date)
                Picker("Statut", selection: $statutSelected) {
                    ForEach(statut, id: \.self) {
                        Text($0)
                    }
                }
            }
            
            Section {
                Button("Enregistrer les modifications") {
                    // Logique de traitement des données du formulaire ici
                }
            }
        }
        .navigationTitle("Mon formulaire")
    }
}

On utilise le $ pour se référer à la variable d’état créée avant le body.

Illustration de l'exemple du formulaire

Voici un autre exemple avec SecureField et Slider :

struct FormView: View {
    @State private var motDePasse: String = ""
    @State private var note: Double = 5.0
    
    var body: some View {
        Form {
            Section(header: Text("Informations de connexion")) {
                SecureField("Mot de passe", text: $motDePasse)
            }
            Section(header: Text("Donnez une note")) {
                Slider(value: $note, in: 0...10, step: 0.5)
                Text("\(note, specifier: "%.1f")/10")
            }

        }
        .navigationTitle("Mon formulaire")
    }
}

On voit que SecureField n’affiche pas les information écrites dans le champ de texte.

Silder quant à lui permet bien à notre utilisateur de spécifier une note comprise en 0 et 10 avec un pas de 0.5.

• Valider une adresse mail

Dans article précédent, je déclarais ma flamme aux regex ❤️

Aujourd’hui je te propose de te montrer comment valider un formulaire en utilisant ces petites choses merveilleuses.

struct FormViewEmail: View {
    @State private var email: String = ""
    @State private var isEmailValid: Bool = false
    
    var body: some View {
        Form {
            Section(header: Text("Mon mail")) {
                TextField("Email", text: $email)
                    .textContentType(.emailAddress)
                    .keyboardType(.emailAddress)
                    .autocapitalization(.none)
                    .disableAutocorrection(true)
                    .onChange(of: email) { _ in
                        validateEmail()
                    }
            }
            
            Section {
                Button(action: {
                    validateForm() // Détaillée dans la section suivante
                }, label :{
                    Text("Valider")
                })
                .disabled(!isEmailValid)
            }
        }
        .navigationTitle("Mon formulaire")
    }
}

Avec la fonction .onChange(), on appelle validateEmail() à chaque fois que la valeur du champ email change.

func validateEmail() {
    let regex = #"^[A-Z0-9a-z._-]+@[A-Za-z.-]+\.[A-Za-z]{2,3}+$"#
    let predicat = NSPredicate(format:"SELF MATCHES %@", regex)
    isEmailValid = predicat.evaluate(with: email)
}

La fonction validateEmail() fait partie de la structure FormViewEmail.
Elle permet de comparer le champ email avec la variable regex, grâce à NSPredicate.
La méthode evaluate(with:) renvoie un booléen.

Valider les informations du formulaire en SwiftUI

Pour valider un formulaire, nous allons modifier un peu le code présenté plus haut. Nous allons également créer une fonction validateForm() qui ouvrira une vue de confirmation.

struct FormViewEmail: View {
    @State private var email: String = ""
    @State private var isEmailValid: Bool = false
    @State private var displayConfirmation: Bool = false

    
    var body: some View {
        NavigationView {
            Form {
                Section(header: Text("Mon mail")) {
                    TextField("Email", text: $email)
                        .textContentType(.emailAddress)
                        .keyboardType(.emailAddress)
                        .autocapitalization(.none)
                        .disableAutocorrection(true)
                        .onChange(of: email) { _ in
                            validateEmail()
                        }
                }
                
                Section {
                    Button(action: {
                        validateForm()
                    }, label :{
                        Text("Valider")
                    })
                    .disabled(!isEmailValid)
                }
            }
            .navigationTitle("Mon formulaire")
            .sheet(isPresented: $displayConfirmation) {
                ConfirmationView()
            }
        }
    }   
// Fonctions validateEmail et validateForm
}

La méthode .sheet() est un modificateur de vue qui permet de présenter une vue modale à partir de la vue actuelle. C’est à dire que c’est comme si une nouvelle fenêtre apparaissait sur notre vue actuelle.

Le paramètre isPresented est un booléen qui détermine si la vue modale doit être présentée ou non. Si la valeur de isPresented est true alors elle est présentée. Ici, c’est la vue ConfirmationView qui s’affiche lorsque que displayConfirmation est true.

Ensuite, on retrouve la fonction validateEmail() vue plus haut.

func validateEmail() {
    let regex = #"^[A-Z0-9a-z._-]+@[A-Za-z.-]+\.[A-Za-z]{2,3}+$"#
    let predicat = NSPredicate(format:"SELF MATCHES %@", regex)
    isEmailValid = predicat.evaluate(with: email)
}

La fonction validateForm() quant à elle change la valeur du booléen displayConfirmation. Si l’email est valide, il passe à true et permet ainsi d’afficher la notification créée dans ConfirmationView.

func validateForm() {
    if isEmailValid {
        displayConfirmation = true
    } else {
        displayConfirmation = false
    }
}

Enfin, la vue ConfirmationView affiche simplement le texte « Votre email a bien été envoyé. ».

struct ConfirmationView: View {
    var body: some View {
        Text("Votre email a bien été envoyé.")
    }
}

Pour un peu plus de clarté de l’article, je te donne le code complet ici :

Code complet de la validation du formulaire
import SwiftUI struct FormViewEmail: View {     @State private var email: String = ""     @State private var isEmailValid: Bool = false     @State private var displayConfirmation: Bool = false          var body: some View {         NavigationView {             Form {                 Section(header: Text("Mon mail")) {                     TextField("Email", text: $email)                         .textContentType(.emailAddress)                         .keyboardType(.emailAddress)                         .autocapitalization(.none)                         .disableAutocorrection(true)                         .onChange(of: email) { _ in                             validateEmail()                         }                 }                                  Section {                     Button(action: {                         validateForm()                     }, label :{                         Text("Valider")                     })                     .disabled(!isEmailValid)                 }             }             .navigationTitle("Mon formulaire")             .sheet(isPresented: $displayConfirmation) {                 ConfirmationView()             }         }     }          func validateEmail() {         let regex = #"^[A-Z0-9a-z._-]+@[A-Za-z.-]+\.[A-Za-z]{2,3}+$"#         let predicat = NSPredicate(format:"SELF MATCHES %@", regex)         isEmailValid = predicat.evaluate(with: email)     }          func validateForm() {         if isEmailValid {             displayConfirmation = true         } else {             displayConfirmation = false         }     } } struct ConfirmationView: View {     var body: some View {         Text("Votre email a bien été envoyé.")     } }


Maintenant que tu sais créer des formulaire en SwiftUI, tu peux t’entraîner encore et encore à jongler entre les différents éléments qui le composent.

Dis nous en commentaire comment tu vas utiliser ton formulaire ✍️

Si tu as aimé cet article, partage le 🫶