Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftUI crash: "SheetBridge: abandoned presentation detected" when dismiss a sheet view (which is triggered by another sheet view )

Tags:

ios

swiftui

Xcode 12 beta 4

I have this ContentView with two different modal views. I want to use sheet(isPresented: onDismiss: content:) to show first view, when it dismissed, automatically show the second view.

This is my code

struct ContentView: View {
    @State var showFirst = false
    @State var showSecond = false

    var body: some View {
        VStack(spacing: 20) {
            Text("showFirst: \(showFirst.description)")
            Text("showSecond: \(showSecond.description)")

            Button("show") {
                showFirst.toggle()
            }
            .sheet(isPresented: $showFirst) {
                showSecond.toggle()
            } content: {
                FirstView(isPresented: $showFirst)
            }

            Text("")
                .sheet(isPresented: $showSecond) {
                    SecondView(isPresented: $showSecond)
                }

        }

    }
}

struct FirstView: View {
    @Binding var isPresented: Bool

    var body: some View {
        VStack {
            Button("close") {
                isPresented = false
            }
            Text("First View")
        }
    }
}

struct SecondView: View {
    @Binding var isPresented: Bool

    var body: some View {
        VStack {
            Button("close") {
                isPresented = false
            }
            Text("Second View")
        }
    }
}

Then I run the code. If I dismiss the model views by drag down gesture, it works. If I dismiss the first view by taping the close button, it crashed when dismiss the second view, and throw a fatal error:

Fatal error: SheetBridge: abandoned presentation detected: file SwiftUI, line 0

My confuse

It looks like when tap the first view's close button and dismiss the second view in any case, $showSecond didn't change to false.

Is there any difference between drag down and manualy toggle $isPresented?

And If I use presentationMode.wrappedValue.dismiss() instead of binding isPredented, it crashed too.

like image 907
YRUsoDiao Avatar asked Aug 07 '20 00:08

YRUsoDiao


1 Answers

Update: retested - fixed in iOS15

The fix is to show second sheet with a bit delay, to give possibility for first sheet to finish completely.

Tested with Xcode 12 / iOS 14

Button("show") {
    showFirst.toggle()
}
.sheet(isPresented: $showFirst) {
    DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {    // << here !!
        showSecond.toggle()
    }
} content: {
    FirstView(isPresented: $showFirst)
}
like image 66
Asperi Avatar answered Oct 04 '22 22:10

Asperi