This particular SwiftUI List, made up of array, I can not seem to select it. Even though I tried with Set(). or @Binding. everything online resource has to offer. Wrong type? or something might have to be about Identifiable? View? Array? I'm totally new here. Related document would be appreciated.
And also how can I access/take the data of selected item and append it into another Array let's say a cart (for e-commerce app for example)
Thank you in advance
import SwiftUI
struct CategoryT1: View {
//
@State private var a1: String?
@State private var a2: SingleItem?
// @Binding private var a3: SingleItem? // Doesn't work & cause other error
// @State private var a3 = Set<SingleItem>() // No Error, but still can't select
@State private var a3: SingleItem? // This couldn't get select
//***** Array 1
let users = ["John", "Jane", "Jim", "Jill"]
//***** Array 2
var arrayOfSingleItem = [
SingleItem(name: "car",
idd: "NYC-0202",
size: "SUV",
price3: "5",
price: "6"),
SingleItem(name: "tank",
idd: "NYC-2",
size: "Big",
price3: "7",
price: "9")
]
//***** Array 3
var dataOfItem =
[
["Candy","0123456","small","95","95" ],
["Cake","005500","10 pound","108","108" ],
]
//*****
var body: some View {
Text("Category")
//**** 1
List(users, id:\.self, selection: $a1) { user in
Text(user)
}
//**** 2
List(arrayOfSingleItem, id:\.self, selection: $a2) { x in
CellRowView(product: x)
}
//**** 3 // This couldn't get select
List(dataOfItem, id:\.self, selection: $a3) { x in
CellRowView(product: SingleItem(
name: x[0],
idd: x[1],
size: x[2],
price3: x[3],
price: x[4])
)
}
}
}
#Preview {
CategoryT1()
}
SingleItem.swiftui would look like this
import SwiftUI
struct SingleItem: Identifiable, Hashable {
let id = UUID()
var name: String
var idd: String
var size: String
var price3: String
var price: String
}
//
struct CellRowView: View {
var product: SingleItem
var body: some View {
VStack(alignment: .leading, spacing: 3) {
Text(product.name)
.foregroundColor(.primary)
.font(.headline)
HStack(spacing: 3) {
Text(product.idd)
}
.foregroundColor(.secondary)
.font(.subheadline)
}
}
}
Try this approach where you use a .tag(a2)
to identify your a2
selection, same for a3
.
Note, your dataOfItem
is an array of array of Strings, re-make it into
a array of strutc to make it easier to work with.
Note, you should also not use x[..]
in your real code. Similarly, do not use id:\.self
in the lists, ensure the items are unique Identifiable
.
To ... access/take the data of selected item and append it into another Array
just use the selections variables a1, a2 or a3
, and to trigger some function when they change, use .onChange(of: ...)
For more info, read the basics of SwiftUI again, especially @State
and List
.
struct ContentView: View {
var body: some View {
CategoryT1()
}
}
struct CategoryT1: View {
@State private var a1: String?
@State private var a2: SingleItem?
@State private var a3: SingleItem?
//***** Array 1
let users = ["John", "Jane", "Jim", "Jill"]
//***** Array 2
var arrayOfSingleItem = [
SingleItem(name: "car",
idd: "NYC-0202",
size: "SUV",
price3: "5",
price: "6"),
SingleItem(name: "tank",
idd: "NYC-2",
size: "Big",
price3: "7",
price: "9")
]
//***** Array 3
var dataOfItem =
[
["Candy","0123456","small","95","95" ],
["Cake","005500","10 pound","108","108" ]
]
var body: some View {
Text("Category")
//**** 1
List(users, id:\.self, selection: $a1) { user in
Text(user)
}
//**** 2
List(arrayOfSingleItem, selection: $a2) { x in
CellRowView(product: x)
.tag(x) // <--- here
}
//**** 3
List(dataOfItemAsArrayOfSingleItem(), selection: $a3) { item in
CellRowView(product: item)
.tag(item) // <--- here
}
// for testing to display the selections
Text("selected a1 user: \(a1 ?? "no user")")
Text("selected a2 SingleItem: \(a2?.name ?? "nothing")")
Text("selected a3 SingleItem: \(a3?.name ?? "nothing")")
.onChange(of: a1) {
print("---> a1 value changed: \(a1 ?? "no user")")
}
}
// --- here
func dataOfItemAsArrayOfSingleItem() -> [SingleItem] {
dataOfItem.map {
SingleItem(name: $0[0], idd: $0[1], size: $0[2], price3: $0[3], price: $0[4])
}
}
}
Ok, for the row highlight, try this alternative example of the code,
where dataOfItemAsArrayOfSingleItem
is an array of [SingleItem]
,
not a function, as in the previous example code.
struct CategoryT1: View {
@State private var a1: String?
@State private var a2: SingleItem?
@State private var a3: SingleItem?
@State private var dataOfItemAsArrayOfSingleItem: [SingleItem] = [] // <--- here
//***** Array 1
let users = ["John", "Jane", "Jim", "Jill"]
//***** Array 2
var arrayOfSingleItem = [
SingleItem(name: "car", idd: "NYC-0202", size: "SUV", price3: "5", price: "6"),
SingleItem(name: "tank", idd: "NYC-2", size: "Big", price3: "7", price: "9")
]
//***** Array 3
var dataOfItem =
[
["Candy","0123456","small","95","95" ],
["Cake","005500","10 pound","108","108" ]
]
var body: some View {
Text("Category")
//**** 1
List(users, id:\.self, selection: $a1) { user in
Text(user)
}
//**** 2
List(arrayOfSingleItem, selection: $a2) { x in
CellRowView(product: x)
.tag(x) // <--- here
}
//**** 3
List(dataOfItemAsArrayOfSingleItem, selection: $a3) { item in
CellRowView(product: item)
.tag(item) // <--- here
}
// for testing to display the selections
Text("selected a1 user: \(a1 ?? "no user")")
Text("selected a2 SingleItem: \(a2?.name ?? "nothing")")
Text("selected a3 SingleItem: \(a3?.name ?? "nothing")")
.onChange(of: a1) {
print("---> a1 value changed: \(a1 ?? "no user")")
}
// <--- here, populate the array on start
.onAppear {
dataOfItemAsArrayOfSingleItem = dataOfItem.map {
SingleItem(name: $0[0], idd: $0[1], size: $0[2], price3: $0[3], price: $0[4])
}
}
}
}