Post

Replies

Boosts

Views

Activity

SwiftUI Table sorts only the first column if the data is loaded later
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.
1
0
458
Mar ’24
ProgressView within Form not showing after the first time
I have a ProgressView in a Form, that's being toggled on and off. The first time it shows correctly, subsequently it does not. Outside of a Form it works correctly. Here's the sample code: struct BugWithProgress: View { @State var toggle: Bool = false var body: some View { Text("in form:").font(.title) Form { Toggle(isOn: $toggle, label: { Text("isOn: \(toggle)") }) if toggle { HStack { ProgressView() Spacer() ProgressView("Working...") Spacer() Text("Working...") } } } .frame(height: 200) Text("outside form:").font(.title) if toggle { HStack { ProgressView() Spacer() ProgressView("Working...") Spacer() Text("Working...") } } } } #Preview { BugWithProgress() } If I toggle it on once, it looks as expected. Here's what it looks like after I toggled it on twice or more: As you can see, the spinning parts are missing within the Form. Any suggestions or workarounds? PS: Is this the correct place for SwiftUI bug reports?
0
0
200
Mar ’24
SwiftUI Picker with .pickerStyle(.segmented) does not work correctly.
I'm trying to display a picker with .pickerStyle(.segmented), including text and an image, but there seems to be a bug. Take the following pickers (not segmented): struct BugInPicker: View { @State var sel = -1 let trashes = ["trash", "trash.fill", "trash.slash", "trash.slash.fill"] var body: some View { VStack { Picker(selection: $sel, label: Text("Trash type")) { ForEach(0 ..< trashes.count) { (i) in Text(self.trashes[i]) } } Picker(selection: $sel, label: Text("Trash type")) { ForEach(0 ..< trashes.count) { (i) in Label(self.trashes[i], systemImage: self.trashes[i]) } } Picker(selection: $sel, label: Text("Trash type")) { ForEach(0 ..< trashes.count) { (i) in HStack { Image(systemName: self.trashes[i]) Text(self.trashes[i]) }.tag(i) } } } } } The first one displays simlple text, the second one includes an image via a label, the third one has image and text manually. And they work fine. As soon as I add .pickerStyle(.segmented) to these pickers, the first one displays text, as it should. The second one also displays text only, the image is not displayed! The third one now has not 4 but 8 entries, each image and each text get their own picker entry. Here with and without the style:
0
1
419
Mar ’24