UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

How can I prevent a navigation link to a child from immediately popping back, when it modifies parent view's data object?

Forums > SwiftUI

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?

4      

I have the same issue, its a "Fix" done by the 14.5 update, did you found any fix?

2      

Change the .onAppear to .onDisappear then it only update the parent view when child view is dismissed.

2      

Same issue here, Did you find a solution for it ??

3      

BUILD THE ULTIMATE PORTFOLIO APP Most Swift tutorials help you solve one specific problem, but in my Ultimate Portfolio App series I show you how to get all the best practices into a single app: architecture, testing, performance, accessibility, localization, project organization, and so much more, all while building a SwiftUI app that works on iOS, macOS and watchOS.

Get it on Hacking with Swift+

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.