I want to use MapKit along with MapAnnotation in SwiftUI. So I can have custom views as map pins and add tap gestures to them later.
But when I run the app, Xcode starts to show so many UI errors:
Publishing changes from within view updates is not allowed, this will cause undefined behavior.
The Code is as simple as we can find, even in apple documentation or the ones below from hacking with swift
import SwiftUI
import MapKit
struct Location: Identifiable {
let id = UUID()
let name: String
let coordinate: CLLocationCoordinate2D
}
struct MapView: View {
@State private var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 51.5, longitude: -0.12), span: MKCoordinateSpan(latitudeDelta: 0.2, longitudeDelta: 0.2))
let locations = [
Location(name: "Buckingham Palace", coordinate: CLLocationCoordinate2D(latitude: 51.501, longitude: -0.141)),
Location(name: "Tower of London", coordinate: CLLocationCoordinate2D(latitude: 51.508, longitude: -0.076))
]
var body: some View {
Map(coordinateRegion: $region, annotationItems: locations) { location in
MapAnnotation(coordinate: location.coordinate) {
Circle()
.stroke(.red, lineWidth: 3)
.frame(width: 44, height: 44)
}
}
.navigationTitle("Map")
.edgesIgnoringSafeArea(.all)
}
}
Would you happen to have any suggestions or workaround?
Can we use MapKit with these huge errors in a Production Release?
UPDATE
Based on recent answer, As a workaround, using a specific Binding<MKCoordinateRegion>()
for the coordinateRegion
, removes the warning/error.
But if you want to move the map based on the selected pin, those errors/warnings will appear again.
struct MapView: View {
@State private var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 51.5, longitude: -0.12), span: MKCoordinateSpan(latitudeDelta: 0.2, longitudeDelta: 0.2))
let locations = [
Location(name: "Buckingham Palace", coordinate: CLLocationCoordinate2D(latitude: 51.501, longitude: -0.141)),
Location(name: "Tower of London", coordinate: CLLocationCoordinate2D(latitude: 51.508, longitude: -0.076))
]
@State var selectedLocation: Location?
var body: some View {
ZStack {
Map(coordinateRegion: Binding<MKCoordinateRegion>(
get: { region },
set: { _ in }
), annotationItems: locations) { location in
MapAnnotation(coordinate: location.coordinate) {
Circle()
.stroke(.red, lineWidth: 3)
.frame(width: 44, height: 44)
.onTapGesture {
selectedLocation = location
}
}
}
}
.onChange(of: selectedLocation) { newValue in
if let location = newValue {
withAnimation {
region = MKCoordinateRegion(center: location.coordinate, span: MKCoordinateSpan(latitudeDelta: 0.2, longitudeDelta: 0.2))
}
}
}
.edgesIgnoringSafeArea(.all)
}
}
As a workaround, using a specific Binding<MKCoordinateRegion>()
for the coordinateRegion
, removes the warning/error for me.
struct MapView: View {
@State var region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 51.5, longitude: -0.12), span: MKCoordinateSpan(latitudeDelta: 0.2, longitudeDelta: 0.2))
let locations = [
Location(name: "Buckingham Palace", coordinate: CLLocationCoordinate2D(latitude: 51.501, longitude: -0.141)),
Location(name: "Tower of London", coordinate: CLLocationCoordinate2D(latitude: 51.508, longitude: -0.076))
]
var body: some View {
Map(coordinateRegion: Binding<MKCoordinateRegion>(
get: { region },
set: { _ in }
), annotationItems: locations) { location in
MapAnnotation(coordinate: location.coordinate) {
Circle().stroke(.red, lineWidth: 3).frame(width: 44, height: 44)
}
}
.navigationTitle("Map")
.edgesIgnoringSafeArea(.all)
}
}