I've read a number of questions about this error that relates to dismissing sheets, but none dealing with SwiftUI's Map. The following code generates this error. Nothing is being updated in the view model. I'm simply passing a binding to a region into the Map initializer. Using a local state variable for region works with no error. I'm running Xcode 14.0. If I remove the @Published property wrapper then the error goes away. So I'm confused as to how the view model should notify the view that the region has changed, perhaps due to location updates.
import SwiftUI
import MapKit
class MM : ObservableObject {
@Published var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 51.507222, longitude: -0.1275), span: MKCoordinateSpan(latitudeDelta: 0.5, longitudeDelta: 0.5))
}
struct SimpleMap: View {
@ObservedObject var mm = MM()
@State private var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 51.507222, longitude: -0.1275), span: MKCoordinateSpan(latitudeDelta: 0.5, longitudeDelta: 0.5))
var body: some View {
//Error
Map(coordinateRegion: $mm.region)
//No Error
//Map(coordinateRegion: $region)
}
}
Did you try updating your code like this?
class MM : ObservableObject {
@Published var _region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 51.507222, longitude: -0.1275), span: MKCoordinateSpan(latitudeDelta: 0.5, longitudeDelta: 0.5))
var region: MKCoordinateRegion {
get { _region }
set {
DispatchQueue.main.async {
self._region = newValue
}
}
}
}
struct SimpleMap: View {
@StateObject var mm = MM()
var body: some View {
//Error
Map(coordinateRegion: $mm.region)
}
}
Making changes to the Publishers or State variables while the view is being updated, causes the issue. To prevent the issue, we should update the Publisher values asynchronously in the main queue. Let me know if this doesn't work.
No matter what you do it is just a working around solution because this warnings is a reported issue of SwiftUI.Map
prior to iOS 17.0.
Publishing changes from within view updates is not allowed, this will cause undefined behavior.
Binding of region:
Whenever the map received a new center, an example from (0, 0) to (10, 10), the map internally sets the region to a sequence of values as below to animate the change [(1, 1), (2, 2), ..., (10, 10)].
You can try replacing the Binding
with a custom to get a closer look.
Map(
coordinateRegion: Binding(get: {
print("Get region: \(region)")
region
}, set: { newValue in
print("Set region: \(newValue)")
region = newValue
})
)
MapAnnotation:
If the map was updated, the visible map annotations will get updated which is totally fine. But MapAnnoation
somehow modifies the internal states of the map causing the warning.
iOS 17.0 and above
Please use the new API, this is the documentation.
iOS 16.0 and lower
final class MapViewModel: ObservableObject {
var region = MKCoordinateRegion(
center: CLLocationCoordinate2D(latitude: 48.876192, longitude: 2.333455),
latitudinalMeters: 3000,
longitudinalMeters: 3000
)
}
struct MapView: View {
@StateObject var viewModel = MapViewModel()
var body: some View {
Map(
coordinateRegion: $viewModel.region,
annotationItems: viewModel.annotationItems,
annotationContent: annotation(for:)
)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.ignoresSafeArea()
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With