How to trigger .onDisappear event for a View inside ForEach loop in SwiftUI?

112 Views Asked by At

It seems that DetailView is only hidden and not removed from the screen, which means that the .onDisappear event is not being triggered for the same view, but is triggered between views. How to achieve a correct logic without moving DetailView outside of ForEach loop?

struct TestItem: Identifiable, Hashable {
    let id = UUID()
    let name: String
}

let items: [TestItem] = [TestItem(name: "Name 1"), TestItem(name: "Name 2"), TestItem(name: "Name 3")]

struct ContentView: View {
    @State var selectedItem: TestItem? = nil
    @State var detailViewPresented: Bool = false
    
    var body: some View {
        List {
            ForEach(items) { item in
                VStack(alignment: .leading) {
                    Text(item.name)
                }
                .onTapGesture {
                    if selectedItem == item && detailViewPresented {
                        detailViewPresented = false
                    } else {
                        detailViewPresented = true
                    }

                    selectedItem = item
                }

                if selectedItem == item && detailViewPresented {
                    DetailView(item: item)
                }
            }
        }
    }
}

struct DetailView: View {
    let item: TestItem

    var body: some View {
        VStack {
            Text("Detail View")
            Text(item.name)
        }
        .onDisappear {
            print("DetailView Disappeared")
        }
    }
}

Here's a link with an example of the problem.

0

There are 0 best solutions below