Implémenter 2 alerts à partir d'une View

Hello bonjour,

Voilà ce code SwiftUI basique, simplifié au maximum mais représentatif d’un cas réel d’application. Une vue, 2 déclencheurs, et 2 .alert.
He bien dans tous les cas, c’est toujours la deuxième alerte qui est prise en compte, jamais la première, pareillement si je toggle-copie-colle, les boutons ou les alertes ou commente une des 2 ?! Le même comportement d’ignorance de la première alerte est systématique et dans la vraie appli, les actions des 2 alertes engagent des traitements différents et s’avèrent donc nécessaires.
Vous pouvez créer vite fait un projet SwiftUI et coller ce code pour reproduire le problème et vous amuser (ne me remerciez pas, c’est avec plaisir :joy:

import SwiftUI
struct OrderCompleteAlert: View {
    @State private var showAlert1 = false
    @State private var showAlert2 = false
    var body: some View {
        VStack {
            Button("Afficher Alerte 1") {
                showAlert1 = true
            }
            Button("Afficher Alerte 2") {
                showAlert2 = true
            }
        }
        .alert(isPresented: $showAlert1) {
            Alert(
                title: Text("Alerte 1"),
                message: Text("Ceci est l'alerte 1"),
                dismissButton: .default(Text("OK"))
            )
        }
        .alert(isPresented: $showAlert2) {
            Alert(
                title: Text("Alerte 2"),
                message: Text("Ceci est l'alerte 2"),
                dismissButton: .default(Text("OK"))
            )
        }
    }
}

struct OrderCompleteAlert_Previews: PreviewProvider {
    static var previews: some View {
        OrderCompleteAlert()
    }
}

D’après mes recherches, il s’agirait d’un problème sur la façon dont SwiftUI redessine la vue!!! C’est confusant, car c’est pourtant un problème tout bête, mais je rame. J’ai essayé des recettes comme Group… if… un switchCase… voire DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) pour décaler les affichages, mais swift n’en veut pas. Alors…, Une idée? :shushing_face: Merci.

Finalement, voilà un code qui marche :

import SwiftUI

struct ContentView: View {
@State private var isShowingPopup1 = false
@State private var isShowingPopup2 = false

var body: some View {
    VStack {
        Button("Afficher popup1") {
            isShowingPopup1 = true
        }
        .padding(10)
        .alert(isPresented: $isShowingPopup1) {
            Alert(
                title: Text("Popup 1"),
                message: Text("Contenu de la popup 1"),
                dismissButton: .default(Text("OK"))
            )
        }
        
        Button("Afficher popup2") {
            isShowingPopup2 = true
        }
        .alert(isPresented: $isShowingPopup2) {
            Alert(
                title: Text("Popup 2"),
                message: Text("Contenu de la popup 2"),
                dismissButton: .default(Text("OK"))
            )
        }
    }
}

}

Les alertes sont directement associées aux boutons et non à la ScrollView globale.

Toujours bon à savoir :sunglasses:

Hello :slight_smile:

Tu peux également créer un objet optionnel, qui affichera une alerte générique:

struct OrderCompleteAlert: View {
    @State private var info: AlertInfo?

    var body: some View {
        VStack {
            Button("Alert 1") {
                info = AlertInfo(
                    title: "Popup 1",
                    message: "Contenu de la popup 1")
            }
            Button("Alert 2") {
                info = AlertInfo(
                    title: "Popup 2",
                    message: "Contenu de la popup 2")
            }
        }
        .alert(item: $info, content: { info in
            Alert(title: Text(info.title),
                  message: Text(info.message))
        })
    }
}

Avec un objet de ce type là :

struct AlertInfo {
    let title: String
    let message: String
}

Ce n’est qu’une suggestion, il doit sûrement y avoir d’autres manières de faire :wink:

Bonjour et merci Anis de me répondre, désolé pour ma réaction tardive à cause des visiteurs vacanciers inattendus. :triumph:
Afin d’exprimer brièvement le problème, je l’ai vraiment trop simplifié .
En réalité, j’ai une ScrollView qui lance une première alerte depuis une VStack de suppression.
Cette ScrollView, en cas de clic sur une des cellules, ouvre aussi une autre vue .sheet, dotée d’une .toolbar, qui elle même propose un sous-menu Menu { … } doté d’un bouton de suppression qui lance aussi une deuxième alerte. Classique!.
Donc deux alertes sont codées, une à la suite et lancée depuis la ScrollView et l’autre codée à la suite de la .toolbar à la suite de la .sheet, et lancée depuis le sous-menu de la .toolbar.
Et … c’est là qu"elles entrent en conflit. Il faut commenter une des deux alertes pour que l’autre marche?!
Après de multiples recherches il semblerait que cela poserait une impossibilité pour SwiftUI de redessiner la vue??!!
Mais j’ai contourné le problème en ne passant par une .toolbar de la .sheet, mais en simulant celle-ci dans une VStack de la ScrollView principale, et c’est robuste.
Donc au final, nous sommes donc tombés sur un cas d’école à résoudre, mais bon, pas le temps!!!
En tout cas merci à toi d’avoir suivi ma question, c’est sympa, et je retourne asap vers flutter :grin: