Home > Software engineering >  onDisappear not called when NagivationView navigates to different view
onDisappear not called when NagivationView navigates to different view

Time:10-30

In a NavigationView, when selecting a different destination, this destination view calls onAppear as expected. However the onDisappear is not called as another destination is selected, at least not immediately, only after a third destination gets selected (see log output below).

struct DetailModel: Identifiable {
    var title: String
    
    var id: String  {
        title
    }
}

struct ContentView: View {
    
    @State var details = [DetailModel(title:"one"), DetailModel(title:"two"), DetailModel(title:"three"), DetailModel(title:"four")]
    
    var body: some View {
        NavigationView {
            List {
                ForEach(details) { detail in
                    NavigationLink(detail.title) {
                        DetailView(detail: detail)
                    }
                }
            }
            .navigationTitle("Details")
        }
    }
}

struct DetailView: View {
    
    var detail: DetailModel
    
    var body: some View {
        Text("DetailView: \(detail.title)")
            .onAppear() {
                print("DetailView: onAppear: \(detail.title)")
            }
            .onDisappear() {
                print("DetailView: onDisappear: \(detail.title)")
            }
    }
}

Log output (extra line between tap events)

DetailView: onAppear: one

DetailView: onAppear: two

DetailView: onDisappear: one
DetailView: onAppear: three

DetailView: onDisappear: two
DetailView: onAppear: four

onDisappear for first detail view only gets called after the second and the third view have been selected.

I understand SwiftUI tries to keep the views for better display performance.

How can I detect that a view is no longer shown so I can perform some action (e.g. pause a video player)?

iOS 15.6 for iPad, XCode 14.0.1, Swift 5

enter image description here

CodePudding user response:

You can try adding .isDetailLink(true) to your NavigationLink, works for me, in activating the .onAppear and .onDisappear as expected.

Note NavigationView is deprecated, use the recommended NavigationStack when you decide to upgrade to ios-16

  • Related