La méthode confirmationDialog() permet d'afficher une boîte de confirmation sous forme de popup, pour permettre à l'usager d'accepter ou de refuser une proposition.
Dans cette fiche :
Le fonctionnement de confirmationDialog ressemble à celui de alert : une variable d'état contrôle si le popup doit être affiché ou non et on peut définir quels boutons seront affichés et quelles actions ils déclencheront.
Voici comment choisir entre une alerte et une boîte de confirmation :
La boîte de confirmation est constituée d'un message suivi d'au moins un bouton, qui permet de réaliser l'action.
Depuis iOS 26, il n'y a plus de bouton d'annulation par défaut. De plus, si un bouton a le rôle .cancel, il ne sera pas affiché. Un bouton .cancel est requis seulement lorsqu'il y a des actions à réaliser lorsque l'usager clique en dehors de la boîte de confirmation.
Je vous propose une technique qui permet d'afficher un bouton d'annulation. Cette technique permet de gérer à la fois le clic sur le bouton d’annulation et la fermeture du dialogue lorsqu’on clique à l’extérieur.
Remarquez l'utilisation d'une vue enfant qui définit chaque élément de la liste. Ceci est essentiel pour que chaque ligne possède son propre état, ce qui permet à SwiftUI d'afficher le popup vis-à-vis la ligne sur laquelle l'usager a cliqué.
Remarquez également comment la vue enfant réussit à modifier la liste, qui est définie dans la vue parent. La vue enfant ne modifie pas directement la liste. Elle reçoit en paramètre une fonction qui permet de modifier la liste.
struct ContentView: View {
@State private var items: [Item] = [
Item(id: 1, code: "ST-001", titre: "Crayon HB"),
Item(id: 2, code: "RL-010", titre: "Règle 30cm"),
Item(id: 3, code: "MS-202", titre: "Souris sans fil"),
Item(id: 4, code: "KB-105", titre: "Clavier mécanique"),
Item(id: 5, code: "NT-330", titre: "Carnet de notes"),
Item(id: 6, code: "ER-005", titre: "Gomme à effacer"),
Item(id: 7, code: "MK-772", titre: "Marqueur noir")
]
var body: some View {
NavigationStack {
List(items) { item in
// vue enfant obligatoire pour que le popup s'affiche au bon endroit
UnItem(item: item) {
items.removeAll { $0.id == item.id } // ceci est le code de la fonction qui est passée en paramètre à la vue enfant
... // autres opérations au besoin
}
}
.toolbar(content: {
ToolbarItem(placement: .principal, content: {
Text("Fournitures scolaires")
})
})
}
}
}
struct UnItem: View {
let item: Item
let onDelete: () -> Void // ce code est défini dans la vue parent
@State private var afficherPopup: Bool = false
var body: some View {
HStack(spacing: 4) {
Image(systemName: "tag")
.padding(10)
.frame(width: 70)
VStack(alignment: .leading) {
Text(item.code)
Text(item.titre)
}
Spacer()
Button(role: .destructive, action: {
afficherPopup = true
}) {
Image(systemName: "trash")
.padding(.trailing)
}
.buttonStyle(.borderless)
.confirmationDialog("Supprimer l'item \(item.titre)?", isPresented: $afficherPopup, titleVisibility: .visible) {
Button("Supprimer", role: .destructive) {
onDelete()
print("Item \(item.code) supprimé.")
}
// depuis iOS 26 : on ajoute un bouton d'annulation qui n'a pas le rôle .cancel
Button("Annuler") {
print("Bouton Annuler cliqué")
nettoyage()
}
// depuis iOS 26 : ce bouton ne sera jamais affiché mais il permet de dire quoi faire quand on clique en dehors du popup
Button("", role: .cancel) {
print("Clic en dehors du popup")
nettoyage()
}
}
} // fin HStack
}
func nettoyage() {
print("Opération nettoyage")
}
}

Le bouton qui permet d'afficher le confirmationDialog pourrait être placé en dehors d'une liste, par exemple dans le bas d'une vue de détail.
Puisque la vue de détail est une vue enfant, elle a déjà son propre état. Elle peut donc contenir le confirmationDialog ainsi que tout le code qui l'entoure.
Dans le cas où la vue de détail doit modifier une liste utilisée ailleurs dans l'application, elle recevra en paramètre une fonction qui permet de modifier cette liste.
Si le confirmationDialog mène à une suppression, une fois la suppression réalisée, il faudra penser à utiliser dismiss() pour refermer la vue de détail.
Remarquez que le confirmationDialog a été attaché directement au bouton pour qu'il apparaisse vis-à-vis ce dernier.
struct DetailsItem: View {
let item: Item
let onDelete: () -> Void // ce code est défini dans la vue parent
@State private var afficherPopup: Bool = false
...
var body: some View {
VStack {
...
Button(role: .destructive, action: {
afficherPopup = true
}) {
Label("Supprimer l'item", systemImage: "trash")
...
}
.confirmationDialog("Supprimer l'item \(item.titre)?", isPresented: $afficherPopup, titleVisibility: .visible) {
Button("Supprimer", role: .destructive) {
onDelete()
dismiss()
}
Button("Annuler") { nettoyage() }
Button("", role: .cancel) { nettoyage() }
}
}
...
}
...
}

▼Publicité