Search code examples
swiftxcodeswiftuixcode11swiftui-navigationlink

Why does modifying the label of a NavigationLink change which View is displayed in SwiftUI?


I have an @EnvironmentObject called word (of type Word) whose identifier property I'm using for the label of a NavigationLink in SwiftUI. For the DetailView that is linked to the NavigationLink, all I have put is this:

struct DetailView: View {
    @EnvironmentObject var word: Word

    var body: some View {
        VStack {
            Text(word.identifier)
            Button(action: {
                self.word.identifier += "a"
            }) {
                Text("Click to add an 'a' to Word's identifier")
            }
        }
    }
}

The ContentView that leads to this DetailView looks like this (I've simplified my actual code to isolate the problem).

struct ContentView: View {

    @EnvironmentObject var word: Word

    var body: some View {
        NavigationView {
            NavigationLink(destination: DetailView()) {
                Text(word.identifier)
            }
        }
    }
}

When I tap the button on the DetailView, I'd expect it to update the DetailView with a new word.identifier that has an extra "a" appended onto it. When I tap it, however, it takes me back to the ContentView, albeit with an updated word.identifier. I can't seem to find a way to stay on my DetailView when the word.identifier being used by the ContentView's NavigationLink is modified. Also, I am running Xcode 11.3.1 and am currently unable to update, so if this is has been patched, please let me know.


Solution

  • Here is workaround solution

    struct DetailView: View {
        @EnvironmentObject var word: Word
    
        @State private var identifier: String = ""
    
        var body: some View {
            VStack {
                Text(self.identifier)
                Button(action: {
                    self.identifier += "a"
                }) {
                    Text("Click to add an 'a' to Word's identifier")
                }
            }
            .onAppear {
               self.identifier = self.word.identifier
            }
            .onDisappear {
               self.word.identifier = self.identifier
            }
        }
    }