In my app i have a MapKit map(), and the map region is the users location, my app then adds a circle on the map around the users location.
How can i make it so that it detects when the user has gone outside of the circle?
Map code:
Map(coordinateRegion: $viewModel.region,
interactionModes: .pan,
showsUserLocation: true,
userTrackingMode: $tracking,
annotationItems: MapLocations,
annotationContent: { location in
MapAnnotation(
coordinate: location.coordinate,
content: {
ZStack{
Circle()
.fill(.blue)
.opacity(0.2)
.frame(width: CGFloat(setWidth), height: CGFloat(setHeight))
.overlay(
RoundedRectangle(cornerRadius: CGFloat(radius))
.stroke(Color.white, lineWidth: 2)
)
.animation(.default)
Circle()
.fill(.red)
.opacity(0.4)
.frame(width: CGFloat(nextWidth), height: CGFloat(nextWidth))
.overlay(
RoundedRectangle(cornerRadius: CGFloat(radius))
.stroke(Color.white, lineWidth: 1)
)
.animation(.default)
}.scaleEffect(Double(UserDefaults.standard.string(forKey: "scaleValue") ?? "1.0")!)
}
)
}
)
.ignoresSafeArea(.all)
.accentColor(Color(.systemBlue))
Region settings:
class ViewModel: NSObject, ObservableObject, CLLocationManagerDelegate {
@Published var region: MKCoordinateRegion = .init(center: .init(latitude: CLLocationManager().location?.coordinate.latitude ?? 11.111, longitude: CLLocationManager().location?.coordinate.longitude ?? 11.111), latitudinalMeters: 1250, longitudinalMeters: 1250)
var locationManager: CLLocationManager?
@Published var selectedZoom: Int = 1 {
didSet {
updateRegion(for: selectedZoom)
}
}
let zoomLevels = [1, 2, 3, 4, 5]
private func updateRegion(for zoom: Int) {
let center = region.center
let distance = getMeters(for: zoom)
region = MKCoordinateRegion(center: center, latitudinalMeters: distance, longitudinalMeters: distance)
if String(zoom) == "1"{
UserDefaults.standard.set("1.0", forKey: "scaleValue")
}
if String(zoom) == "2"{
UserDefaults.standard.set("2.0", forKey: "scaleValue")
}
if String(zoom) == "3"{
UserDefaults.standard.set("3.0", forKey: "scaleValue")
}
if String(zoom) == "4"{
UserDefaults.standard.set("4.0", forKey: "scaleValue")
}
if String(zoom) == "5"{
UserDefaults.standard.set("5.0", forKey: "scaleValue")
}
}
private func getMeters(for zoom: Int) -> CLLocationDistance {
1250 / Double(zoom)
}
func checkIfLocationServicesIsEnabled() {
if CLLocationManager.locationServicesEnabled() {
locationManager = CLLocationManager()
locationManager!.delegate = self
locationManager?.desiredAccuracy = kCLLocationAccuracyBest
}else{
print("Location is not enabled, please enable")
}
}
func recenterMap() {
region = MKCoordinateRegion(center: .init(latitude: CLLocationManager().location?.coordinate.latitude ?? 11.111, longitude: CLLocationManager().location?.coordinate.longitude ?? 11.111), latitudinalMeters: 1250, longitudinalMeters: 1250)
updateRegion(for: selectedZoom)
}
private func checkLocationAuthorization() {
guard let locationManager = locationManager else { return }
switch locationManager.authorizationStatus{
case .notDetermined:
locationManager.requestWhenInUseAuthorization()
case .restricted:
print("your location is restricted likely due to parental controls")
case .denied:
print("You have denied this app to use your location, please change it in settings.")
case .authorizedAlways, .authorizedWhenInUse:
region = MKCoordinateRegion(center: locationManager.location!.coordinate, span: MapDetails.defualtSpan)
@unknown default:
break
}
}
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
checkLocationAuthorization()
}
}
Map Model View
//
// MapViewModel.swift
// HideAndSeek
//
// Created by Phil Trevor on 01/10/2022.
//
import MapKit
import SwiftUI
enum MapDetails {
static let startingLocation = CLLocationCoordinate2D(latitude: 37.33, longitude: -0-121.89)
static let defualtSpan = MKCoordinateSpan(latitudeDelta: 0.04, longitudeDelta: 0.04)
}
class MapViewModel: NSObject, ObservableObject, CLLocationManagerDelegate {
@Published var region = MKCoordinateRegion(center: MapDetails.startingLocation, span: MapDetails.defualtSpan)
var locationManager: CLLocationManager?
func checkIfLocationServicesIsEnabled() {
if CLLocationManager.locationServicesEnabled() {
locationManager = CLLocationManager()
locationManager!.delegate = self
locationManager?.desiredAccuracy = kCLLocationAccuracyBest
}else{
print("Location is not enabled, please enable")
}
}
private func checkLocationAuthorization() {
guard let locationManager = locationManager else { return }
switch locationManager.authorizationStatus{
case .notDetermined:
locationManager.requestWhenInUseAuthorization()
case .restricted:
print("your location is restricted likely due to parental controls")
case .denied:
print("You have denied this app to use your location, please change it in settings.")
case .authorizedAlways, .authorizedWhenInUse:
region = MKCoordinateRegion(center: locationManager.location!.coordinate, span: MapDetails.defualtSpan)
@unknown default:
break
}
}
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
checkLocationAuthorization()
}
}
I can attach a screenshot if needed.
I hope i explained it well enough.
Summary:
When the user moves outside of the circle it triggers some code