SwiftUI runtime warning for Binding extension: "Publishing changes from within view updates is not allowed"
darvelo opened this issue · 1 comments
Description
I'm not sure if I'm doing something wrong with my code, but I get this runtime warning from SwiftUI when opening an alert or dialog:
I have an error handler in my VM which publishes an alert or dialog enum to the VM state, which is then read by SwiftUI. My problem was that the alert or dialog wouldn't be presented if a sheet was presented on top already, so I created a ViewModifier
to reuse for both the main view and the sheet:
When the event is published, it goes to both modifier instances, and I believe that's what triggers the warning from SwiftUI inside the swiftui-navigation
library.
FWIW I get a message in the console when not using swiftui-navigation
, but it's not the same as this runtime warning:
2023-06-05 16:40:06.401215+0700 test-navigation-bug[914:99772] [Presentation] Attempt to present <SwiftUI.PlatformAlertController: 0x102072e00> on <_TtGC7SwiftUI19UIHostingControllerGVS_15ModifiedContentVS_7AnyViewVS_12RootModifier__: 0x101809800> (from <_TtGC7SwiftUI19UIHostingControllerGVS_15ModifiedContentVS_7AnyViewVS_12RootModifier__: 0x101809800>) which is already presenting <_TtGC7SwiftUI29PresentationHostingControllerVS_7AnyView_: 0x102035000>.
Though I'm not sure how best to handle this case where I need the alert or dialog to show even when a sheet is presented.
Checklist
- I have determined whether this bug is also reproducible in a vanilla SwiftUI project.
- If possible, I've reproduced the issue using the
main
branch of this package. - This issue hasn't been addressed in an existing GitHub issue or discussion.
Expected behavior
No SwiftUI warning at runtime.
Actual behavior
SwiftUI runtime warning from Binding
extension.
Steps to reproduce
Try out the reproducible example at https://github.com/darvelo/swiftui-runtime-error-sample
SwiftUI Navigation version information
0.7.2
Destination operating system
iOS 16
Xcode version information
14.3 (14E222b)
Swift Compiler version information
swift-driver version: 1.75.2 Apple Swift version 5.8 (swiftlang-5.8.0.124.2 clang-1403.0.22.11.100)
Target: arm64-apple-macosx13.0
Hi @darvelo, it is not correct to make changes to your model inside the trailing closure of confirmationDialog
(or really any of the navigation view modifiers, e.g. sheet
, popover
, etc.). This is why you are getting the runtime warning:
🟣 Modifying state during view update, this will cause undefined behavior.
It is telling you that you are updating state at a time that it is not allowed to update state. All you can do in the confirmationDialog
trailing closure is build up view that SwiftUI you present.
Here is a plain, vanilla SwiftUI demo that demonstrates the same behavior:
import SwiftUI
struct ContentView: View {
@State var isPresented = false
var body: some View {
Button("Tap") {
self.isPresented = true
}
.sheet(isPresented: self.$isPresented) {
let _ = self.isPresented = false
}
}
}
Since this is not an issue with the library I am going to convert it to a discussion, and if you have more questions you can post there.