I’m learning how to use MapKit. I have user location on I want to add annotations. When I set an annotation, it moves with me. It doesn’t stay in place. How can I make it stay in place? I know it has something to do with the region property but I cant quite figure it out.
struct MapView: View {
@StateObject private var viewModel = MapViewModel()
@State private var locations = [Location]()
var body: some View {
ZStack {
Map(coordinateRegion: $viewModel.region, showsUserLocation: true, annotationItems: locations) { location in
MapMarker(coordinate: CLLocationCoordinate2D(latitude: viewModel.region.center.latitude, longitude: viewModel.region.center.longitude))
}
.ignoresSafeArea()
Circle()
.fill(.pink)
.opacity(0.3)
.frame(width: 32, height: 32)
}
.onAppear {
viewModel.checkIfLocationServicesAreEnabled()
}
.overlay(
Button {
let newLocation = Location(id: UUID(), name: "Random Name", color: "Cyan", latitude: viewModel.region.center.latitude, longitude: viewModel.region.center.longitude, items: [Item(id: UUID(), name: "Random Name 1"), Item(id: UUID(), name: "Random Name 2"), Item(id: UUID(), name: "Random Name 3")])
locations.append(newLocation)
} label: {
Image(systemName: "plus")
.padding()
.background(.black.opacity(0.75))
.foregroundColor(.white)
.font(.title)
.clipShape(Circle())
.padding(.trailing)
}, alignment: .bottomTrailing)
}
}
enum MapDetails {
static let startingLocation = CLLocationCoordinate2D(latitude: 37.331516, longitude: -121.891054)
static let defaultSpan = MKCoordinateSpan(latitudeDelta: 0.05, longitudeDelta: 0.05)
}
final class MapViewModel: NSObject, ObservableObject, CLLocationManagerDelegate {
@Published var region = MKCoordinateRegion(center: MapDetails.startingLocation, span: MapDetails.defaultSpan)
@Published var showingAlert = false
var locationManager: CLLocationManager?
func checkIfLocationServicesAreEnabled() {
if CLLocationManager.locationServicesEnabled() {
locationManager = CLLocationManager()
locationManager!.delegate = self
} else {
showingAlert = true
}
}
private func checkLocationAuthorization() {
guard let locationManager = locationManager else { return }
switch locationManager.authorizationStatus {
case .notDetermined:
locationManager.requestWhenInUseAuthorization()
case .restricted:
print("Show alert saying location access is restricted")
case .denied:
print("You have denied location permission. Go into app settings in order to change it.")
case .authorizedAlways, .authorizedWhenInUse:
region = MKCoordinateRegion(center: locationManager.location!.coordinate, span: MapDetails.defaultSpan)
@unknown default:
break
}
}
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
checkLocationAuthorization()
}
}