Louis Couture
Louis Couture

Reputation: 82

How to show two alerts in swift ui one followed by the other

I want to make an application where the users will press one button, and then, when they have chosen an option, another alerts pops up. When I try something similar to this;

struct ContentView: View {
@State private var showingAlert = false
@State private var showingAlertII = false

var body: some View {
        Button(action: {
            self.showingAlert = true
        }, label: {
            Text("button")
                .alert(isPresented: $showingAlert) {
                    Alert(title: Text("Option one or two"), message: Text("choose"), primaryButton: .default(Text("one"), action: {

        // do some specific actions
                        self.showingAlertII = true
                    }), secondaryButton: .default(Text("two"), action: {
                       //do some other stuff
                        self.showingAlertII = true
                    }))

            }
            .alert(isPresented: $showingAlertII) {
                    Alert(title: Text("Option A or B"), message: Text("choose"), primaryButton: .default(Text("Split"), action: {
                        // do something
                    }), secondaryButton: .default(Text("B"), action: {
                        //do something 
                    }))

            }
        })

No alert is showing. Note that there is another tutorial: How can I have two alerts on one view in SwiftUI? similar to this, however, using .first notation and returning one or another will not work for me because I want both to be shown, one after another.

Upvotes: 2

Views: 1320

Answers (1)

KevinP
KevinP

Reputation: 2738

You cannot make two .alert calls directly behind each other without overwriting one of them. The key is to get all the logic inside a single .alert call.

import SwiftUI

enum ActiveAlert {
    case first, second, third
}

struct ContentView: View {
    @State private var showingAlert = false
    @State private var activeAlert: ActiveAlert = .first

    var body: some View {
        Button(action: {
            self.showAlert(.first)
        }, label: {
            Text("button")
            .alert(isPresented: $showingAlert) {
                switch activeAlert {
                    case .first:
                        return Alert(title: Text("First Alert"), dismissButton: .default(Text("Next"), action: {
                            self.showAlert(.second)
                        }))
                    case .second:
                        return Alert(title: Text("Second Alert"), dismissButton: .default(Text("Next"), action: {
                            self.showAlert(.third)
                        }))
                    case .third:
                        return Alert(title: Text("Third Alert"), dismissButton: .default(Text("Ok"), action: {
                            //...
                        }))
                }
            }
        })
    }

    func showAlert(_ active: ActiveAlert) -> Void {
        DispatchQueue.global().async {
            self.activeAlert = active
            self.showingAlert = true
        }
    }
}

Upvotes: 6

Related Questions