I have a problem with the presentationBackground modifier. When using it in a real application, I noticed strange behavior upon returning to the root view, where it seems like two views overlap each other. In a sample app created for the purpose of this question, it looks like this:
Step to reproduce:
Here is example (working) code
import SwiftUI
struct ContentView: View {
@State var newItem: String?
@State var sheetPresented = false
var body: some View {
NavigationStack {
Button {
sheetPresented = true
} label: {
Text("Open sheet")
}
.sheet(isPresented: $sheetPresented) {
NavigationStack {
Button {
newItem = "New item"
} label: {
Text("Add new item")
}
.navigationDestination(item: $newItem) { item in
NavigationStack {
NewItemDetails(item: item)
}
}
}
}
}
}
}
struct NewItemDetails: View {
@Environment(\.dismiss) var dismiss
@State var openSheet = false
let item: String
init(item: String) {
self.item = item
}
var body: some View {
VStack(spacing: 20) {
Button {
dismiss()
} label: {
Text(item)
}
Button {
openSheet = true
} label: {
Text("Open sheet")
}
}
.sheet(isPresented: $openSheet) {
Button {
openSheet = false
} label: {
Text("After dismiss tap to 'New item' or Back")
}
.presentationBackground {
Color.red
}
}
}
}
#Preview {
ContentView()
}
Does anyone know why this is happening? Is it a bug, or is it more likely due to an oversight or incorrect view structure on my part?
This seems like a SwiftUI bug to me. I'd suggest submitting feedback to Apple.
For now, you can work around this by adding a presentationBackground
to the first sheet as well. If you use .background
, it will look the same as if you did not add a presentationBackground
modifier.
.sheet(isPresented: $sheetPresented) {
NavigationStack {
Button {
newItem = "New item"
} label: {
Text("Add new item")
}
.navigationDestination(item: $newItem) { item in
// don't nest another NavigationStack here!
NewItemDetails(item: item)
}
}
.presentationBackground(.background) // <----
}