EDIT: It happens on iOS 14.2 - 14.5, but not 14.1 or 14.0. It's a SwiftUI regression. I don't know a workaround so far.
I'm having issues with the SwiftUI List selection, when the user scrolls. Selected cells that get scrolled offscreen and then become visible again are not displayed as selected.
Am I missing something or is this a SwiftUI bug?
It seems like the internal SwiftUI List coordinator is using UITableView and doesn't correctly update the cell state for the selection state.
struct Item: Identifiable, Hashable {
let id: Int
}
class ViewModel: ObservableObject {
@Published var selectedItems: Set<Int>
@Published var items: Array<Item>
init() {
self.items = [Item(id: 1), Item(id: 2), Item(id: 3), Item(id: 4), Item(id: 5),
Item(id: 6), Item(id: 7), Item(id: 8), Item(id: 9), Item(id: 10),
Item(id: 11), Item(id: 12), Item(id: 13), Item(id: 14), Item(id: 15),]
self.selectedItems = []
}
}
struct ContentView: View {
@ObservedObject var context: ViewModel
var body: some View {
// Alternative also doesn't work.
// List(context.items, id: \.id, selection: $context.selectedItems) { item in
// Text("\(item.id)").id(item.id)
// }
// .environment(\.editMode, .constant(.active))
List(context.items, selection: $context.selectedItems) { item in
Text("\(item.id)")
}
.environment(\.editMode, .constant(.active))
}
}
The console output:
ListSelection[6659:3960182] [Assert] Attempted to call -cellForRowAtIndexPath: on the table view while it was in the process of updating its visible cells, which is not allowed. Make a symbolic breakpoint at UITableViewAlertForCellForRowAtIndexPathAccessDuringUpdate to catch this in the debugger and see what caused this to occur. Perhaps you are trying to ask the table view for a cell from inside a table view callback about a specific row? Table view: <TtC7SwiftUIP33_BFB370BA5F1BADDC9D83021565761A4925UpdateCoalescingTableView: 0x10381ec00; baseClass = UITableView; ...; dataSource: <TtGC7SwiftUIP10$1b198497819ListCoreCoordinatorGVS_20SystemListDataSourceSi_GOS_19SelectionManagerBoxSi: 0x10340a930>>
