I am displaying a table using data from a custom data type (in this case, General) which contains a number of properties (name, policyId, category etc)
When I select a row I am using the following @state vars to select and sort the data
@State private var selectedPolicyIDs = Set<General.ID>()
@State private var sortOrder = [KeyPathComparator(\General.policyId)]
My selection gives me the UUID of the data object, but I want to access a different property (in this case the policyId property rather than UUID) to pass it to a function
This is the code:
struct General: Codable, Hashable, Identifiable {
var id = UUID()
let policyId: Int?
let name: String?
}
Table(networkController.allPoliciesDetailedGeneral, selection: $selectedPolicyIDs, sortOrder: $sortOrder) {
TableColumn("Name", value: \.name!)
TableColumn("Category", value: \.category!.name)
TableColumn("ID") {
policy in
Text(String(policy.policyId ?? 0))
}
}
.onChange(of: sortOrder) { newOrder in
networkController.allPoliciesDetailedGeneral.sort(using: newOrder)
}
Is there a way that I can map the UUID to the policyId value so that I can access that when I select a row - or that I can have access to the entire object, to be able to pass it to the function?
I also need to be able to select multiple items, so I am wanting to pass a set of policyIds (or entire General objects) instead of the current set of UUIDs that I can access.
I am thinking that it would be possible to do a computed property to dynamically match the UUID from the selection with the relevant item from the array, or another calculation that triggers each time the item is selected, but my brain is drawing a blank coming up with it.
You have some array of General objects that is your data source for the table, lets call it
var dataSource: [General]
then you can convert the selected ID's from selectedPolicyIDs to an array of objects doing
let selectedObjects = dataSource.filter { selectedPolicyIDs.contains($0.id) }
or if you want the policyId instead you can add map
let selectedObjects = dataSource.filter { selectedPolicyIDs.contains($0.id) }
.map(\.policyId)
If you only need/want to select single objects you could change the solution to
var selection: General.ID?
if let selection, let object = dataSource.first(where: { $0.id == selection })
//... call function
}
It’s not clear when you want to call this function, if it’s directly or when some button is clicked for instance but if’s directly then add an onChange
modifier for the selectedPolicyIDs
property