All examples regarding SwiftUI Tables and sorting work fine, but they also have all the data available immediately.
If I load the data in .task
, sorting only works on the first column.
Test data:
struct Customer: Identifiable {
let id = UUID()
let name: String
let email: String
let creationDate: Date
}
func parseDate(from text: String) -> Date {
let formatter = DateFormatter()
formatter.dateFormat = "dd/MM/yyyy"
return formatter.date(from: text) ?? Date()
}
func getTestData() -> [Customer] {
return [
Customer(name: "John Smith",
email: "john.smith@example.com",
creationDate: parseDate(from: "04/11/2015")),
Customer(name: "Jane Doe",
email: "jane.doe@example.com",
creationDate: parseDate(from: "29/04/2009")),
Customer(name: "Bob Johnson",
email: "bob.johnson@example.com",
creationDate: parseDate(from: "01/08/2010"))]
}
And here the view:
- table 1 populates the array in the initializer
- table 2 loads the content in
.task
, initially it is empty - table 3 loads the content in
.task
, initially it contains one dummy object
struct SortableTable: View {
@State var customers1 = getTestData()
@State var customers2: [Customer] = []
@State var customers3: [Customer] = [Customer(name: "", email: "", creationDate: Date())]
@State private var sortOrder1 = [KeyPathComparator(\Customer.name)]
@State private var sortOrder2 = [KeyPathComparator(\Customer.name)]
@State private var sortOrder3 = [KeyPathComparator(\Customer.name)]
var body: some View {
Table(customers1, sortOrder: $sortOrder1) {
TableColumn("name", value: \.name)
TableColumn("email", value: \.email)
TableColumn("joined at", value: \.creationDate) { customer in
Text(customer.creationDate, style: .date)
}
}
.frame(height: 200)
.onChange(of: sortOrder1) { oldOrder, newOrder in
customers1.sort(using: newOrder)
}
Table(customers2, sortOrder: $sortOrder2) {
TableColumn("name", value: \.name)
TableColumn("email", value: \.email)
TableColumn("joined at", value: \.creationDate) { customer in
Text(customer.creationDate, style: .date)
}
}
.frame(height: 200)
.onChange(of: sortOrder2) { oldOrder, newOrder in
customers2.sort(using: newOrder)
}
.task {
customers2 = getTestData()
}
Table(customers3, sortOrder: $sortOrder3) {
TableColumn("name", value: \.name)
TableColumn("email", value: \.email)
TableColumn("joined at", value: \.creationDate) { customer in
Text(customer.creationDate, style: .date)
}
}
.frame(height: 200)
.onChange(of: sortOrder3) { oldOrder, newOrder in
customers3.sort(using: newOrder)
}
.task {
customers3 = getTestData()
}
Spacer()
}
}
The result is that table 1 and table 3 can be sorted by all columns, while table 2 can only be sorted (for whatever reason) be the first column:
HIH and let me know, if I misunderstood something.