SWIFTUI List object .onTapGesture or Click event not setting values ?. Bug or issue with way .sheet works?

SWIFTUI List object .onTapGesture or Click event not setting values ?. Bug or issue with way .sheet works? On list object .onTapGesture / selection of the row I wanted send the Index /value to another view via .Sheet option And 90% of the time I get 0 (wrong value) help / guide , a newbie Code snippets for main view & popup view below

//Main view with list object:
import SwiftUI

struct SwiftUIView_Sheet_Test_Main: View {
    let workflow_trn_data:[workflow_transaction_data] = [
        .init(mst_rec_id: 100, work_task: "Task 100"),
        .init(mst_rec_id: 101, work_task: "Task 101")
    ]
    
    @State private var selected_Mst_record:Int32 = 0
    @State private var isPopupSheetActive:Bool = false
    
    var body: some View {
        Text("Sheet Test Main View")
        NavigationStack{
            List() {
                ForEach(0..<workflow_trn_data.count ,id: \.self) { index in
                    if(index == 0 ) {
                        // heading patch
                        HStack{
                            Text("Rec ID")
                                .font(.title3)
                                .frame(minWidth:70)
                            Spacer()
                            Text("work_task")
                                .font(.title3)
                                .frame(minWidth:100)
                            Spacer()
                            Text("Status")
                                .font(.title3)
                                .frame(minWidth:70)
                            Spacer()
                        }
                    }
                    // data
                    HStack{
                        Text("\(workflow_trn_data[index].mst_rec_id)")
                            .onTapGesture {
                            print("onTapGesture: \(workflow_trn_data[index].mst_rec_id)")
                            selected_Mst_record = workflow_trn_data[index].mst_rec_id
                            isPopupSheetActive = true
                        }
                        Spacer()
                        Text("\(workflow_trn_data[index].work_task)")
                        Spacer()
                        
                        // button
                        Button(action: {
                            selected_Mst_record = workflow_trn_data[index].mst_rec_id
                            isPopupSheetActive = true
                        }, label: {
                            Image(systemName:"ellipsis.circle.fill")
                                .foregroundColor(.blue)
                        })
                    }
                    
                }
            }
        }
        .sheet(isPresented: $isPopupSheetActive) {
            SwiftUIView_Sheet_Test_Popup(value_from_caller:selected_Mst_record)
        }
    }


}

#Preview {
    SwiftUIView_Sheet_Test_Main()
}

struct workflow_transaction_data: Identifiable {
    let mst_rec_id: Int32
    let work_task: String
    var id: Int32 {
        mst_rec_id
    }
}

// popup view
import SwiftUI

struct SwiftUIView_Sheet_Test_Popup: View {
    let value_from_caller:Int32?
    
    var body: some View {
        Text("Sheet Test Popup Child view")
        Text("value recived from caller:\(value_from_caller ?? -1)")
    }
}

#Preview {
    SwiftUIView_Sheet_Test_Popup(value_from_caller:100)
}
code-block
Answered by DTS Engineer in 847898022

First you can use sheet(item:onDismiss:content:) to present the sheet with content from your data source. For example:

struct SwiftUIView_Sheet_Test_Main: View {
    let workflow_trn_data: [workflow_transaction_data] = [
        .init(mst_rec_id: 100, work_task: "Task 100"),
        .init(mst_rec_id: 101, work_task: "Task 101")
    ]

    @State private var selectedTransaction: workflow_transaction_data? = nil

    var body: some View {
        NavigationStack {
            List {
                Section {
                    ForEach(workflow_trn_data) { item in
                        WorkflowTransactionRow(item: item) { selectedTransaction = $0 }
                    }
                } header: {
                    ListHeaderRow()
                }
            }
            .navigationTitle("Sheet Test Main View")
            .navigationBarTitleDisplayMode(.inline)
        }
        .sheet(item: $selectedTransaction) { transaction in
            SwiftUIView_Sheet_Test_Popup(value_from_caller: transaction.mst_rec_id)
        }
    }
}

struct WorkflowTransactionRow: View {
    let item: workflow_transaction_data
    let onSelect: (workflow_transaction_data) -> Void

    var body: some View {
        HStack {
            Text("\(item.mst_rec_id)")
                .onTapGesture {
                    onSelect(item)
                }
            Spacer()
            Text(item.work_task)
            Spacer()
            Button {
                onSelect(item)
            } label: {
                Image(systemName: "ellipsis.circle.fill")
                    .foregroundColor(.blue)
            }
        }
    }
}

struct ListHeaderRow: View {
    var body: some View {
        HStack {
            Text("Rec ID").font(.title3).frame(minWidth: 70)
            Spacer()
            Text("Work Task").font(.title3).frame(minWidth: 100)
            Spacer()
            Text("Status").font(.title3).frame(minWidth: 70)
            Spacer()
        }
    }
}

I think, on line 60 in your code above, you need to add selected_Mst_record in so it becomes:

.sheet(isPresented: $isPopupSheetActive) { selected_Mst_record in

It's something to do with the getter, I think.

Accepted Answer

First you can use sheet(item:onDismiss:content:) to present the sheet with content from your data source. For example:

struct SwiftUIView_Sheet_Test_Main: View {
    let workflow_trn_data: [workflow_transaction_data] = [
        .init(mst_rec_id: 100, work_task: "Task 100"),
        .init(mst_rec_id: 101, work_task: "Task 101")
    ]

    @State private var selectedTransaction: workflow_transaction_data? = nil

    var body: some View {
        NavigationStack {
            List {
                Section {
                    ForEach(workflow_trn_data) { item in
                        WorkflowTransactionRow(item: item) { selectedTransaction = $0 }
                    }
                } header: {
                    ListHeaderRow()
                }
            }
            .navigationTitle("Sheet Test Main View")
            .navigationBarTitleDisplayMode(.inline)
        }
        .sheet(item: $selectedTransaction) { transaction in
            SwiftUIView_Sheet_Test_Popup(value_from_caller: transaction.mst_rec_id)
        }
    }
}

struct WorkflowTransactionRow: View {
    let item: workflow_transaction_data
    let onSelect: (workflow_transaction_data) -> Void

    var body: some View {
        HStack {
            Text("\(item.mst_rec_id)")
                .onTapGesture {
                    onSelect(item)
                }
            Spacer()
            Text(item.work_task)
            Spacer()
            Button {
                onSelect(item)
            } label: {
                Image(systemName: "ellipsis.circle.fill")
                    .foregroundColor(.blue)
            }
        }
    }
}

struct ListHeaderRow: View {
    var body: some View {
        HStack {
            Text("Rec ID").font(.title3).frame(minWidth: 70)
            Spacer()
            Text("Work Task").font(.title3).frame(minWidth: 100)
            Spacer()
            Text("Status").font(.title3).frame(minWidth: 70)
            Spacer()
        }
    }
}
SWIFTUI List object .onTapGesture or Click event not setting values ?. Bug or issue with way .sheet works?
 
 
Q