How do I centre map over current location Swift

Viewed 40

I'm pretty new to coding in general and to get to this point I've been following multiple tutorials online which may have caused my code to be jumbled so I apologise for this.

I have started creating an app using MapKit with map annotations in my home town. I am currently living abroad so my location is not where these map annotations are. When I accept the location permissions the map defaults to the first annotation pin where I would like it to default to my current location.

My code is below and any help/explanation would be greatly appreciated.

Locations View Model

'''class LocationsViewModel: ObservableObject {
    
@Published var locations: [Location]

@Published var mapLocation: Location {
    didSet {
        updateMapRegion(location: mapLocation)
    }
}

@Published var mapRegion: MKCoordinateRegion = MKCoordinateRegion()
let mapSpan = MKCoordinateSpan(latitudeDelta: 0.05, longitudeDelta: 0.05)


init() {
    let locations = LocationsDataServices.locations
    self.locations = locations
    self.mapLocation = locations.first!
    self.updateMapRegion(location: locations.first!)
}

private func updateMapRegion(location: Location) {
    withAnimation(.easeInOut) {
        mapRegion = MKCoordinateRegion(
            center: location.coordinates,
            span: mapSpan)
    }
}

func showNextLocation(location: Location) {
    withAnimation(.easeInOut) {
        mapLocation = location
        
    }
}

}'''

Locations Services Model

'''import MapKit

enum MapDetails {
static let startingLocation = CLLocationCoordinate2D(latitude: ***, longitude: ***)
static let defaultSpan = MKCoordinateSpan(latitudeDelta: 0.05, longitudeDelta:      0.05)
}

final class LocationServicesModel: NSObject, ObservableObject,  CLLocationManagerDelegate {



@Published var region = MKCoordinateRegion(center: MapDetails.startingLocation, span: MapDetails.defaultSpan)

var locationManager: CLLocationManager?

func checkIfLocationServicesIsEnabled() { 
    if CLLocationManager.locationServicesEnabled() {
        locationManager = CLLocationManager()
        locationManager!.delegate = self 
        locationManager?.desiredAccuracy = kCLLocationAccuracyBest
    } else {
        print("turn on location manager")
    }
}

private func checkLocationAuthorisation() { 
    guard let locationManager = locationManager else { return }
    
    switch locationManager.authorizationStatus {
        
    case .notDetermined:
        locationManager.requestWhenInUseAuthorization()
    case .restricted:
        print("location is restricted")
    case .denied:
        print("location has been denied, go into settings to change permission")
    case .authorizedAlways, .authorizedWhenInUse:
        
        break
    @unknown default:
        break
    }

}

func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
    checkLocationAuthorisation()
}'''

The code works to a degree, the map annotations are placed correctly and it does show my current location but I'm not sure where or how I'd get the map to centre of the user location on acceptance of location permissions instead of the coordinates I have input above.

Thanks!

1 Answers

Once you have the required permission you need to invoke startUpdatingLocation()

locationManager.startUpdatingLocation()

This starts the generation of updates that report the user’s current location. These updates are available to you via the delegate method:

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    // Ensure we have an actual location in the update.
    guard let location = locations.last else { return }

    // Do something with the location.
}

The location is a CLLocation and you can extract the coordinate from that.

let span = MKCoordinateSpan(latitudeDelta: 0.009, longitudeDelta: 0.009)
let region = MKCoordinateRegion(center: location.coordinate, span: span)
mapView.setRegion(region, animated: true)
Related