I have navigation setup in SwiftUI where both parent view & child view reads from @StateObject
and child view writes to the state object. The thing is that, when child view writes to state object, the parent view detects change in the object and tries to recompute/redraw the view, which pops the child view from navigation stack.
Below is a simple demo of what I am trying to achieve.
The parent view is ContentView
and the child view is MsgDetailView
.
The parent view shows Msg
's read status on the screen.
The child view has onAppear
trigger that marks message as read, when user navigates to the child view to read the message.
This message updates notified to the parent view, and the parent view redraws the view, which immediately pops the child view, and put screen back to the parent view.
class MsgList : ObservableObject {
@Published var msgs : [String:Msg] = [
"id1":Msg(id: "id1", read:false, content: "Hello"),
"id2":Msg(id: "id2", read:false, content: "World")
]
}
struct Msg {
var id : String
var read = false
var content : String
}
struct MsgDetailView: View {
@ObservedObject var msgList : MsgList
var msg : Msg
var body: some View {
VStack {
Text("Message id: \(msg.id)")
}.onAppear {
// Mark message as read when this view appears.
msgList.msgs[msg.id]!.read = true
}
}
}
struct ContentView: View {
@StateObject var msgList = MsgList()
var body: some View {
NavigationView {
VStack {
ForEach(msgList.msgs.sorted(by: {$0.key < $1.key}), id:\.key) { _, msg in
NavigationLink(destination:
MsgDetailView(msgList: msgList, msg: msg)
){
Text("Msg read: \(msg.read ? "Yes" : "No")")
}
}
}
}
}
}
When child view is modifying data, I want parent view to not pop the navigation.
What is the proper way to manage navigation if child view & parent view reads and writes to the same @StateObject/ObservedObject?