Hello, my name is John Su. Welcome to my homepage. I'm a senior technical director, technical artist, game engineer, VFX artist, and art-lover.
by John
Recently, I encountered an interesting issue while working with SwiftUI sheets and view updates. Let me share my experience and the solution I found.
I was implementing a sheet presentation in SwiftUI where I needed to show details of a selected knot. Instead of using the standard sheet(item:content:) modifier (due to async-related issues), I created a computed binding property:
private var someKnotSelected: Binding<Bool> {
Binding<Bool>(
get: { selectedKnot != nil || isAdding},
set: { newValue in
if !newValue {
selectedKnot = nil
isAdding = false
}
}
)
}
And used it with the sheet modifier:
List {
NamedKnotItems
NewKnotItem
}
.ropeToolBar(rope: rope)
.padding(.top, 5)
.sheet(isPresented: someKnotSelected, onDismiss: {
}) {
KnotDetailSheet(knot: selectedKnot, rope: rope)
.presentationDetents([.medium, .large])
.presentationDragIndicator(.visible)
.presentationBackgroundInteraction(.enabled)
}
The problem arose when I noticed that the sheet content wasn’t updating properly when selectedKnot changed. Even though the binding was correctly tracking the selection state, the view inside the sheet wasn’t reflecting the changes.
The key to fixing this issue was adding the .id() modifier to the sheet content:
.sheet(isPresented: someKnotSelected, onDismiss: {
}) {
KnotDetailSheet(knot: selectedKnot, rope: rope)
.id(selectedKnot?.id) // This is crucial!
.presentationDetents([.medium, .large])
.presentationDragIndicator(.visible)
.presentationBackgroundInteraction(.enabled)
}
The .id() modifier forces SwiftUI to treat the view as a new instance when the ID changes. In this case, when selectedKnot changes, the .id(selectedKnot?.id) modifier ensures that SwiftUI recreates the view with the new data, rather than trying to update the existing view.
This is particularly important when using custom bindings with sheets, as SwiftUI’s default view update mechanism might not catch all the changes in the underlying data.
When working with sheets in SwiftUI, especially with custom bindings, remember to:
.id() modifier when the sheet content needs to update based on changing dataThis solution helped me maintain the async-friendly approach while ensuring proper view updates in the sheet presentation.
views: tags: swiftui