Image de présentation d’un écran iOS illustrant les shapes en SwiftUI, plusieurs forme de différentes couleurs sont présentes

Fields

Image de présentation d’un écran iOS illustrant les shapes en SwiftUI, plusieurs forme de différentes couleurs sont présentes

Fields

Les fields (champs de saisie) sont des composants interactifs. Ils permettent, dans la plupart des cas, de récupérer des données saisies par l’utilisateur. Ça peut être un simple login + mot de passe, un formulaire complet pour collecter des informations nécessaires à l’application, ou encore un champ de recherche pour filtrer et retrouver des données spécifiques.

Le composant TextFields

Le composant TextField est un champ de saisie qui permet à l’utilisateur d’entrer du texte par défaut.


struct TextFieldView: View {
    @State private var name: String = ""

    var body: some View {
        VStack {
            TextField("Entre ton nom", text: $name)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .padding()

            Text("Nom saisi : \(name)")
        }
    }
}
Comme pour les derniers composants (Button, Slider et Toggle), le fait que l’utilisateur modifie la vue (ici en changeant la propriété name) implique qu’il faut bien penser à autoriser SwiftUI à mettre à jour la vue avec le property wrapper @State. Le TextField prend en valeur cette propriété avec $name, c’est un Two-Way Binding, comme pour le Slider, c’est le composant qui est maître de cette propriété. Enfin, le TextField prend en première intention un placeholder, c’est le texte qui sera affiché par défaut sur le champ, permettant à l’utilisateur de savoir quelle action est attendue de sa part, comme ici « Entre ton nom ».

 Gestion du Clavier

Selon le type de donnée que tu récupères, tu peux adapter le clavier affiché à ton utilisateur. Il te suffit d’utiliser le modificateur .keyboardType() avec en paramètre le type de clavier souhaité.


struct TextFieldView: View {
    @State private var name: String = ""
    @State private var phoneNumber: String = ""
    @State private var size: String = ""
    @State private var mail: String = ""
    @State private var url: String = ""
    var body: some View {
        VStack {
            TextField("Entre ton nom", text: $name)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .keyboardType(.default)
            TextField("Entre ton téléphone", text: $phoneNumber)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .keyboardType(.phonePad)
            TextField("Entre ton mail", text: $mail)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .keyboardType(.emailAddress)
            TextField("Entre ta taille", text: $size)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .keyboardType(.decimalPad)
            TextField("Entre ton site web", text: $url)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .keyboardType(.URL)
        }
    }
}

.default

.phonePad

.emailAddress

.decimalPad

.URL

Champ de Saisie Sécurisé SecureField

Le composant SecureField fonctionne exactement de la même façon que le TextField, sauf qu’il va cacher les entrées de l’utilisateur avec des pastilles noires pour chaque caractère. Idéal pour les mots de passe.


struct SecureFieldExample: View {
    @State private var password: String = ""

    var body: some View {
        VStack {
            SecureField("Entre ton mot de passe", text: $password)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .padding()
            Text("Mot de passe saisi : \(password)")
    }
}

Champ de Texte Multiligne TextEditor

Un TextEditor permet d’écrire du texte sur plusieurs lignes (contrairement à TextField qui est monoligne).
Remarque TextEditor ne supporte pas de placeholder directement. Il faut ajouter un Text conditionnel.


struct TextEditorView: View {
    @State private var message: String = ""

    var body: some View {
        VStack {
            HStack {
                TextEditor(text: $message)
                    .frame(height: 40)
                    .padding(8)
                    .background(Color.gray.opacity(0.2))
                    .cornerRadius(10)
                    .overlay(RoundedRectangle(cornerRadius: 10).stroke(Color.gray, lineWidth: 1))

                Image(systemName: "paperplane.fill")
                    .font(.title2)
                    .foregroundColor(.blue)
                    .padding()
            }
            .padding()
        }
    }
}

Personnalisation des Fields

Les composants Fields peuvent bien évidemment être personnalisés à ta convenance.

struct TextFieldView: View {
    @State private var name: String = ""

    var body: some View {
        VStack {
            TextField("Entre ton nom", text: $name)
                .padding()
                .font(.title3)
                .background(Color.orange.opacity(0.5))
                .cornerRadius(10)
                .shadow(radius: 5)
                .padding()
        }
    }
}

Composition de vue

struct struct TextFieldView: View {
    @State private var text: String = ""

    var body: some View {
        HStack {
            Image(systemName: "magnifyingglass")
                .foregroundColor(.gray)

            TextField("Rechercher...", text: $text)
                .padding(8)

            if !text.isEmpty {
                Image(systemName: "xmark.circle.fill")
                    .foregroundColor(.gray)
                    .onTapGesture { text = "" }
            }
        }
        .padding(8)
        .background(RoundedRectangle(cornerRadius: 8).stroke(Color.orange, lineWidth: 1))
        .padding()
    }
}

Gérer les Événements Utilisateur

SwiftUI fournit plusieurs modificateurs pour gérer les événements liés aux champs de texte. Le premier que je te présente est le paramètre onEditingChanged, qui permet d’observer, via une valeur booléenne, si l’utilisateur est en train d’éditer un champ ou non.

Dans notre exemple, nous l’utilisons pour mettre en orange le champ activé par l’utilisateur.

struct 
struct TextFieldView: View {
    @State private var firstName: String = ""
    @State private var lastName: String = ""
    @State private var isEditingFirstName: Bool = false
    @State private var isEditingLasttName: Bool = false
    
    var body: some View {
        TextField("Entre ton prénom", text: $firstName, onEditingChanged: { editing in
            isEditingFirstName = editing
        })
        .padding()
        .background(
            RoundedRectangle(cornerRadius: 8)
                .stroke(isEditingFirstName ? Color.orange : Color.gray, lineWidth: 2)
        )
        .padding()
        TextField("Entre ton nom", text: $lastName, onEditingChanged: { editing in
            isEditingLasttName = editing
        })
        .padding()
        .background(
            RoundedRectangle(cornerRadius: 8)
                .stroke(isEditingLasttName ? Color.orange : Color.gray, lineWidth: 2)
        )
        .padding()
    }
}

Valider une ou des entrées

La méthode .onSubmit est un modificateur qui s’exécute lorsqu’un utilisateur valide la saisie dans un champ de texte. Sur iPhone, ça se produit lorsqu’il appuie sur le bouton « Retour«  du clavier.

struct TextFieldView: View {
    @State private var name: String = ""
    @State private var confirmationMessage: String = ""

    var body: some View {
        VStack(spacing: 20) {
            TextField("Entre ton nom", text: $name)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .onSubmit {
                    confirmationMessage = "Salut, \(name) !"
                }
                .padding()

            if !confirmationMessage.isEmpty {
                Text(confirmationMessage)
                    .font(.headline)
                    .foregroundColor(.orange)
            }
        }
        .padding()
    }
}

Avec un bouton

struct struct TextFieldView: View {
    @State private var name: String = ""
    @State private var confirmationMessage: String = ""
    
    var body: some View {
        VStack(spacing: 20) {
            TextField("Entre ton nom", text: $name)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .padding()
            
            Button("Valider") {
                confirmationMessage = "\(name)"
            }
            .buttonStyle(.borderedProminent)
            .tint(.orange)
            .padding()
            
            Text(confirmationMessage)
                .font(.headline)
                .fontWeight(.black)
                .fontWidth(.expanded)
            
        }
        .padding()
    }
}

Tips

Les champs de saisie sont des zones sensibles dans une application, car c’est là que l’utilisateur entre directement des données. Pour éviter les erreurs inutiles, il est essentiel de contrôler et valider ce qu’il peut saisir.

Utilise le bon type de clavier (.emailAddress, .phonePad, .numberPad) pour guider l’utilisateur et éviter les erreurs de format.

Ajoute des validations dynamiques (ex : vérifier qu’une adresse email contient @).

Empêche les saisies invalides (ex : limiter un champ numérique à une plage de valeurs).

Améliore l’expérience utilisateur avec des aides visuelles (icône d’erreur, bordure rouge si la saisie est incorrecte).

Un champ bien configuré permet d’éviter les erreurs améliore l’expérience utilisateur.

Tips

Les champs de saisie sont des zones sensibles dans une application, car c’est là que l’utilisateur entre directement des données. Pour éviter les erreurs inutiles, il est essentiel de contrôler et valider ce qu’il peut saisir.

Utilise le bon type de clavier (.emailAddress, .phonePad, .numberPad) pour guider l’utilisateur et éviter les erreurs de format.

Ajoute des validations dynamiques (ex : vérifier qu’une adresse email contient @).

Empêche les saisies invalides (ex : limiter un champ numérique à une plage de valeurs).

Améliore l’expérience utilisateur avec des aides visuelles (icône d’erreur, bordure rouge si la saisie est incorrecte).

Un champ bien configuré permet d’éviter les erreurs améliore l’expérience utilisateur.