It seems the swift team is tightening the screws on concurrency, but ...
The error is:
Main actor-isolated property 'buttonMaxWidth' can not be mutated from a Sendable closure
Where:
@State private var buttonMaxWidth: CGFloat = 120
Now looking under the hood:
@preconcurrency @inlinable nonisolated public func onPreferenceChange<K>(_ key: K.Type = K.self, perform action: @escaping @Sendable (K.Value) -> Void) -> some View where K : PreferenceKey, K.Value : Equatable
but, I wonder why they did not mark this func as @MainActor isolated? I suspect the 2m lines behind that would have to be refactored.
for now my solution 1 is to assume
.onPreferenceChange(ButtonWidthPreferenceKey.self) { newSize in
MainActor.assumeIsolated {
buttonMaxWidth = newSize
}
}
What's the point of all these rules if we can say ignore the rules in one line ?
For solution 2, you can be more pedantic and declare a MainActor isolated func that you can than open a Task that calls it, too much work ...
.onPreferenceChange(ButtonWidthPreferenceKey.self) { newSize in
Task { @MainActor in
setButtonMaxWidth(newSize)
}
}