Swiftui Sheet Gets Dismissed the First Time It Is Presented

SwiftUI sheet gets dismissed the first time it is presented

I had the same problem in an app. After a great deal of research, I found that making the variable an observed object fixed the problem in SwiftUI 1, and it seems to be in SwiftUI 2. I do remember that it was an intermittent problem on an actual device, but it always happened in the simulator. I wish I could remember why, maybe when the sheet appears it resets the bound variable?, but this code fixes the problem:

import SwiftUI
import Combine

struct ContentView: View {
var body: some View {
NavigationView {
NavigationLink(destination: DetailsView()) {
Text("Open Details View")
}
}
.navigationViewStyle(StackNavigationViewStyle())
}
}

struct DetailsView: View {

@ObservedObject var sheetIsPresented = SheetIsPresented.shared

var body: some View {
VStack {
Button("Open") {
sheetIsPresented.value.toggle()
}
}.sheet(isPresented: $sheetIsPresented.value, content: {
SheetView()
})
}
}

struct SheetView: View {

var body: some View {
Color.red
}
}

final class SheetIsPresented: NSObject, ObservableObject {
let objectWillChange = PassthroughSubject<Void, Never>()

static let shared = SheetIsPresented()

@Published var value: Bool = false {
willSet {
objectWillChange.send()
}
}

}

struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}

Tested on Xcode 12.1, iOS 14.1 in simulator.

SwiftUI cannot dismiss the second sheet presented

The problem is that onDismiss is too early to set up second sheet, first one is still on screen and bound to state.

Here is a solution. Tested with Xcode 11.4 / iOS 13.4

private func loadSecondView() {
if activeSheet == .second {
activeSheet = .first
} else {
activeSheet = .second

// give time to close first sheet
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
self.isShowingPhotoSheet = true
}
}
}


Related Topics



Leave a reply



Submit