Show User Location on Map Swiftui

Show user coordinates SwiftUI

All you have to do is make the showsUserLocation var true.(Look at the docs)

func makeUIView(context: UIViewRepresentableContext<MapView>) ->  MKMapView {

let map = MKMapView()
let coordinate = CLLocationCoordinate2D(latitude: 55.757485, longitude: 37.632179)
map.region = MKCoordinateRegion(center: coordinate, latitudinalMeters: 100, longitudinalMeters: 100)
let annotation = MKPointAnnotation()
annotation.coordinate = coordinate

// new code...
map.showsUserLocation = true

map.delegate = context.coordinator

map.addAnnotation(annotation)
return map

}

As of iOS 14 you can use the native SwiftUI Map. This might be easier to work with than bridging to UIKit

SwiftUI mapkit set region to user's current location

Here's one possible solution to this:

final class LocationManager: NSObject, ObservableObject {
@Published var location: CLLocation?
@Published var region = MKCoordinateRegion(
center: CLLocationCoordinate2D(latitude: 38.898150, longitude: -77.034340),
span: MKCoordinateSpan(latitudeDelta: 0.5, longitudeDelta: 0.5)
)
private var hasSetRegion = false

private let locationManager = CLLocationManager()

override init() {
super.init()

self.locationManager.delegate = self

self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.distanceFilter = kCLDistanceFilterNone
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
}
}

extension LocationManager: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if let location = locations.last {
self.location = location

if !hasSetRegion {
self.region = MKCoordinateRegion(center: location.coordinate,
span: MKCoordinateSpan(latitudeDelta: 0.5, longitudeDelta: 0.5))
hasSetRegion = true
}
}
}
}

struct ShowMapView: View {
@ObservedObject private var locationManager = LocationManager()

var homeLocation : [AnnotationItem] {
guard let location = locationManager.location?.coordinate else {
return []
}
return [.init(name: "Home", coordinate: location)]
}

var body: some View {
Map(coordinateRegion: $locationManager.region, annotationItems: homeLocation) {
MapPin(coordinate: $0.coordinate)
}
.frame(height: 300)
}
}

In this solution, the region is published by the location manager. As soon as a location is received, the region is centered on that spot (in didUpdateLocations). Then, a boolean flag is set saying the region has been centered initially. After that boolean is set, it no longer updates the region. This will let the user still drag/zoom, etc.

I also changed your code for putting down the pin a little bit. You were force-unwrapping location, which is nil until the first location is set by the location manager, causing a crash. In my edit, it just returns an empty array of annotation items if there isn't a location yet.

Swiftui + Core Location: Map fails to center on user

That is exactly your problem. Location data will ALWAYS lag, just like any other retrieved data. What you need to consider is a mechanism to update your views when you get updates.

The best way to do that is to import Combine in your LocationManager class and use a PassthroughSubject like this:

let objectWillChange = PassthroughSubject<Void, Never>()
@Published var region = MKCoordinateRegion() {
willSet { objectWillChange.send() }
}

That allows you to subscribe to your publisher in the map and get updates. You will find many tutorials regarding this.

Retrieve user current location using SwiftUI and MapKit

Create instance of CLLocationManager:

var locManager = CLLocationManager()
locManager.requestWhenInUseAuthorization()

then get the details:

var currentLocation: CLLocation!

if( CLLocationManager.authorizationStatus() == .authorizedWhenInUse ||
CLLocationManager.authorizationStatus() == .authorizedAlways){

currentLocation = locManager.location

}

then to get longitude or latitude:

let longitude = currentLocation.coordinate.longitude
let latitude = currentLocation.coordinate.latitude

If you'd like to perform it inside a swiftUI view script, create instance:

@ObservedObject var locationManager = LocationManager()

Get them separately:

var userLatitude: String {
return "\(locationManager.lastLocation?.coordinate.latitude ?? 0)"

var userLongitude: String {
return "\(locationManager.lastLocation?.coordinate.longitude ?? 0)"


Related Topics



Leave a reply



Submit