Skk
Skk

Reputation: 198

SwiftUI on iOS 16 - Multiple selection in a List does not work

This is on iOS 16. I'm on Xcode 14.0.

I have the following view:

struct ContentView: View {
    struct Ocean: Identifiable, Hashable {
        let name: String
        let id = UUID()
    }
    
    private var oceans = [
        Ocean(name: "Pacific"),
        Ocean(name: "Atlantic"),
        Ocean(name: "Indian"),
        Ocean(name: "Southern"),
        Ocean(name: "Arctic")
    ]
    
    @State private var multiSelection = Set<UUID>()
    
    var body: some View {
        NavigationView {
            List(oceans, selection: $multiSelection) {
                Text($0.name)
            }
            .navigationTitle("Oceans")
            .toolbar { EditButton() }
        }
        Text("\(multiSelection.count) selections")
    }
}

This code is taken from https://developer.apple.com/documentation/SwiftUI/List.

I am expecting to see that whenever I click on the "Edit" button, I should be able to select a few items, press "Done", then the bottom would still show the number of items I have selected. However, this is not the case:

enter image description here

I tried to use a debugger, and I found out that whenever I click on "Done" after selecting the items, the multiSelection resets itself to be empty. This used to work on Xcode 13. I can't really find anything on Apple's documentation regarding changes to the EditButton or changes to the List struct.

Update

I filed a bug report and Apple got back to me, they said this is expected behaviour. I guess I misinterpreted the use case for this list selection here.

Upvotes: 2

Views: 2181

Answers (2)

Xaxxus
Xaxxus

Reputation: 1839

i think the issue here is that your identifiers for your list are not stable. Basically every time an ocean object is created, it gets a new UUID. You dont want that UUID to change.

Any time your state property changes, the view may or may not get rebuilt, causing your oceans to get regenerated.

Try storing your oceans in like this:

@State var oceans: [Ocean] = [
    Ocean(name: "Pacific"),
    Ocean(name: "Atlantic"),
    Ocean(name: "Indian"),
    Ocean(name: "Southern"),
    Ocean(name: "Arctic")
]

Alternatively, you can use the ocean's name as its identifier instead of a UUID that is generated each time its created.

Upvotes: 0

malhal
malhal

Reputation: 30746

Before iOS 16 the selection only worked when in editing mode. Now it works also when not editing so I believe the problem is now the selection is being cleared when done is being tapped (so it can be used when not editing).

I think we need to send feedback to request 2 selection bindings, one for editing and one for when not-editing.

Upvotes: 1

Related Questions