Closed Kondamon closed 2 years ago
We have figured out the root cause of this issue. It is related to passing an ObservableObject with Routes
from the parent to the child. Both hold the same instance of this object (see code example). However, this leads to not updating the view anymore when e.g. pushing a "view" to routes. Why is this happening and is it related to Node or a SwiftUI bug?
@main
struct FlowStacksApp: App {
var body: some Scene {
WindowGroup {
ParentView()
}
}
}
struct ParentView: View {
@ObservedObject var model = ChildModel()
var body: some View {
ChildView(model: getModel())
}
private func getModel() -> ChildModel {
// When you comment out the next line, everything works fine
model.routes = [.root(.home)]
return model
}
}
struct ChildView: View {
enum Screen {
case home, coverScreen
}
@ObservedObject var model = ChildModel()
var body: some View {
Router($model.routes) { screen, _ in
switch screen {
case .home:
Button("Press here should show cover screen") {
model.routes.presentCover(.coverScreen)
}
case .coverScreen:
Text("Cover screen successfully shown!")
}
}
}
}
class ChildModel: ObservableObject {
@Published var routes: Routes<ChildView.Screen>
init(routes: Routes<ChildView.Screen> = [.root(.home)]) {
self.routes = routes
}
}
Hi @Kondamon!
// When you comment out the next line, everything works fine
model.routes = [.root(.home)]
This line is the problem. The getModel()
function is called whenever ParentView
's body
is evaluated. It mutates the model's routes
property, which causes the ParentView's body to be re-evaluated. This continues in an infinite loop.
Even without the infinite loop, you would be continually resetting the routes state to the beginning whenever you tried to present a new screen:
Thank you, this helped me to resolve that issue!
We have found out a strange behaviour that have occurred a few times now during implementation. We don't know if it's related to using multiple ObservableObjecs within the views and passing them around from the parent to a few childs or is it something else.
After a button click the routes are updated as expected but after the routes update e.g. via coverScreen, no rendering update happens in SwiftUI. So it looks like the if the button click doesn't have any effect on the UI. I have played around with using a custom .id(increasingNumber) on the related view and modified the id with the button click. After the 2nd click all buttons responds as expected again. However, do you have any idea why does this happen when using FlowStacks?