I have a simple example of a List with multiple selection. When I run it on macOS, and select an item from the list, it works fine but I get a warning in the console:
Publishing changes from within view updates is not allowed, this will cause undefined behavior
Interestingly, it doesn't produce a purple 'issue' in the Issues navigator, but as I change selection, I keep getting this warning.
Also, the warning doesn't show when running the same code on iOS.
Here is code to reproduce it:
struct TestListSelection: View {
let testArray = [TestItem(itemValue: 1), TestItem(itemValue: 2), TestItem(itemValue: 3), TestItem(itemValue: 4)]
@ObservedObject var listOptions: TestListViewModel
var body: some View {
List (selection: $listOptions.multipleSelection) {
Section("Header") {
ForEach (testArray, id: \.self) { item in
Button {
print("row tapped - \(item.itemValue)")
} label: {
VStack {
HStack {
Text(item.itemString)
}
}
}
.buttonStyle(.plain)
}
}
}
.listStyle(.plain)
}
}
public struct TestItem: Identifiable, Hashable {
public let id = UUID()
let itemValue: Int
var itemString: String {
get {
return "test \(itemValue)"
}
}
}
@MainActor
public class TestListViewModel: NSObject, ObservableObject {
@Published public var multipleSelection = Set<TestItem>()
}
I annotated the view model with @MainActor
as suggested in other threads, but it doesn't silence the warning.
If I move the multipleSelection
into the view itself, and make it a @State
variable (bypassing the viewModel completely), it works and doesn't produce a warning. But I need it work so I can pass in selection from the UIKit part of the app as well. I also can't migrate to @Observable because my main project has to support iOS15 and above.
Any clue why this is happening on macOS specifically, and what I can do to avoid it?