Gary
Gary

Reputation: 1895

Refresh view when navigating to it

In SwiftUI 2, when I navigate from a parent view to a child view and then back to the parent view, the parent view does not refresh its contents. How can I force it to refresh its contents?

In order to test if the contents get refreshed, in my parent view I displayed a random number using the following code:

Text("Random number is \(Int.random(in: 1..<100))")

When I navigate to a child view, and then I tap the Back button in the navigation bar to return to this parent view, the random number displayed remains the same. This indicates that the view is not refreshing.

How can I force the view to refresh itself whenever the user navigates back to it?

Upvotes: 2

Views: 4849

Answers (2)

KlausM
KlausM

Reputation: 291

You could force SwiftUI to update the list by adding an .id(viewID) view modifier to the source view with an @State variable, in this case called "viewID". Then update this viewID in .onDisappear() of the destination view:

struct ContentView: View {
    @State private var viewID: Int = 0
    
    var body: some View {
        NavigationView {
            VStack {
                
                Text("Hello, random world number \(Int.random(in: 1...100))")
                    .padding()
                    .id(viewID)
                                
                NavigationLink(
                    destination: destinationView,
                    label: { labelView })
            }
        }
    }
    
    private var labelView: some View {
        Text("Go to Destination View")
    }
    
    private var destinationView: some View {
        return Text("I am the Destination.")
            .onDisappear{
                viewID += 1
            }
    }
}

Upvotes: 3

rohanphadte
rohanphadte

Reputation: 1018

SwiftUI is declarative - as in you define the states the view could be in and Swift UI will take care of when it should update. In your example, there is no change in state, and thus, the view doesn't update.

If you want the view to refresh, you need to update state on appear events. You can do so like this:

struct ContentView: View {
    @State var intValue: Int = 0

    var body: some View {
        Text("Random number is \(self.intValue)")
        .onAppear {
            intValue = Int.random(in: 1..<100)
        }
    }
}

You'll find that if you push a different view using a NavigationView/NavigationLink, and then navigate back, the label should update with a new random value.

Upvotes: 1

Related Questions