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

ToolBar

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

ToolBar

Ce cours sera assez rapide, car j’ai préféré l’isoler du cours sur la navigation, bien qu’il y soit directement lié. La toolbar est un modificateur de NavigationStack permettant d’ajouter des boutons d’action, de navigation ou d’interaction, ainsi que des menus contextuels dans la barre de navigation.

Toolbar avec un bouton simple

Le .toolbar fonctionne sensiblement comme le .sheet vu dans le cours précédent. C’est un modificateur de la pile NavigationStack, qui permet d’ajouter des éléments interactifs dans la barre de navigation. Tu places ton élément déclencheur dans les accolades de .toolbar, qui prend en charge un ToolbarItem. Ici, nous ajoutons un bouton à la barre de navigation.

struct ContentView: View {
    @State private var message = "Bienvenue sur mon app"
    @State private var isEditing = false

    var body: some View {
        NavigationStack {
            VStack {
                if isEditing {
                    TextField("Entre un message", text: $message)
                        .textFieldStyle(RoundedBorderTextFieldStyle())
                        .padding()
                } else {
                    Text(message)
                        .font(.title)
                        .padding()
                }
            }
            .navigationTitle("Accueil")
            .toolbar {
                ToolbarItem(placement: .navigationBarTrailing) {
                    Button(isEditing ? "Valider" : "Modifier") {
                        isEditing.toggle()
                    }
                }
            }
        }
    }
}

Custom un bouton dans la ToolBar

Tu peux personnaliser ton bouton dans la toolbar comme tu le souhaites.


struct ToolBarView: View {
    @State private var message = "Bienvenue sur mon app"
    @State private var isEditing = false

    var body: some View {
        NavigationStack {
            VStack {
                if isEditing {
                    TextField("Entre un message", text: $message)
                        .textFieldStyle(RoundedBorderTextFieldStyle())
                        .padding()
                } else {
                    Text(message)
                        .font(.title)
                        .padding()
                }
            }
            .navigationTitle("Accueil")
            .toolbar {
                ToolbarItem(placement: .navigationBarTrailing) {
                    Button(action: { isEditing.toggle() }) {
                        HStack {
                            Image(systemName: isEditing ? "checkmark.circle.fill" : "pencil.circle.fill")
                                .foregroundStyle(isEditing ? .green : .blue)
                            Text(isEditing ? "Valider" : "Modifier")
                                .fontWeight(.semibold)
                        }
                        .padding(8)
                        .background(RoundedRectangle(cornerRadius: 10).fill(isEditing ? Color.green.opacity(0.2) : Color.blue.opacity(0.2)))
                    }
                }
            }
        }
    }
}

Toolbar avec une icône (SF Symbols)

On retrouve souvent des icônes SF Symbols dans la toolbar, car elles permettent d’afficher des informations claires et directes pour l’utilisateur.


struct ToolBarView: View {
    @State private var notificationsEnabled = false

    var body: some View {
        NavigationStack {
            VStack {
                Text(notificationsEnabled ? "Notifications activées" : "Notifications désactivées")
                    .font(.title)
                    .padding()
            }
            .navigationTitle("Notifications")
            .toolbar {
                ToolbarItem(placement: .navigationBarTrailing) {
                    Button {
                        notificationsEnabled.toggle()
                    } label: {
                        Image(systemName: notificationsEnabled ? "bell.fill" : "bell.slash.fill")
                            .foregroundStyle(notificationsEnabled ? .green : .gray)
                    }
                }
            }
        }
    }
}

Toolbar avec deux boutons (gauche & droite)

Si tu observes bien les exemples précédents, je place les éléments de la toolbar à droite en utilisant .navigationBarTrailing.

Cependant, tu peux aussi les positionner à gauche avec .navigationBarLeading, ou même en bas de l’écran avec .bottomBar. Ça permet d’adapter l’interface en fonction des besoins de l’application et d’améliorer l’expérience utilisateur.


struct ToolBarView: View {
    @State private var count = 0
    @State private var showAlert = false

    var body: some View {
        NavigationStack {
            VStack {
                Text("Nombre d'éléments : \(count)")
                    .font(.title)
                    .padding()
            }
            .navigationTitle("Ma Liste")
            .toolbar {
                ToolbarItem(placement: .navigationBarLeading) {
                    Button {
                        showAlert = true
                    } label: {
                        Image(systemName: "questionmark.circle")
                    }
                }

                ToolbarItem(placement: .navigationBarTrailing) {
                    Button {
                        count += 1
                    } label: {
                        Image(systemName: "plus")
                    }
                }
            }
            .alert("Comment utiliser ?", isPresented: $showAlert) {
                Button("OK", role: .cancel) { }
            } message: {
                Text("Appuie sur ➕ pour ajouter un élément.")
            }
        }
    }
}

struct ToolBarView: View {
    @State private var fruits = ["Mangue", "Kiwi", "Ananas", "Pastèque"]
    
    var body: some View {
        NavigationStack {
            List(fruits, id: \.self) { item in
                Text(item)
            }
            .navigationTitle("Fruits")
            .toolbar {
                ToolbarItem(placement: .navigationBarTrailing) {
                    Menu {
                        Button("A → Z") { fruits.sort() }
                        Button("Z → A") { fruits.sort(by: >) }
                        Button("Réinitialiser") { fruits = ["Mangue", "Kiwi", "Mirabelle", "Pastèque"] }
                    } label: {
                        Image(systemName: "line.3.horizontal.decrease.circle")
                    }
                }
            }
        }
    }
}

Tips

Il y a un endroit important que nous n’avons pas encore vu en détail dans Xcode, mais que nous explorerons plus tard, l’inspecteur de projet (Project Navigator). Pour y accéder, c’est simple, dans ton arborescence, sélectionne le fichier tout en haut qui porte le nom de ton projet et qui est représenté par l’icône de l’App Store.

Dans cet inspecteur, tu te trouves plus précisément dans l’onglet “General”, qui permet de configurer des aspects clés de ton application, tels que :

→ Les destinations supportées (iPhone, iPad, Mac, Apple Vision)

→ La version minimale d’iOS requise

→ L’identité du projet (Bundle Identifier, version, build)

→ Les orientations supportées (Portrait, Paysage, etc.)

C’est ici que tu gères les configurations générales de ton application. Pour accéder à d’autres paramètres, tu peux naviguer entre les onglets Signing & Capabilities, Build Settings, Info, etc..

Tips

Il y a un endroit important que nous n’avons pas encore vu en détail dans Xcode, mais que nous explorerons plus tard, l’inspecteur de projet (Project Navigator). Pour y accéder, c’est simple : dans ton arborescence, sélectionne le fichier tout en haut qui porte le nom de ton projet et qui est représenté par l’icône de l’App Store.

Dans cet inspecteur, tu te trouves plus précisément dans l’onglet “General”, qui permet de configurer des aspects clés de ton application, tels que :

→ Les destinations supportées (iPhone, iPad, Mac, Apple Vision)

→ La version minimale d’iOS requise

→ L’identité du projet (Bundle Identifier, version, build)

→ Les orientations supportées (Portrait, Paysage, etc.)

C’est ici que tu gères les configurations générales de ton application. Pour accéder à d’autres paramètres, tu peux naviguer entre les onglets Signing & Capabilities, Build Settings, Info, etc..