I am new to swift . I am trying to show user location with Pin . I added the permission in Info Plist to allow the user access . I am using the storyboard and I tried to edit the schema also added the default location but it did not fixed the problem . I am using CLLocationManagerDelegate with MapKit.
Here is my code for view controller ..
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate {
@IBOutlet var mapView: MKMapView!
let manager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.delegate = self
manager.requestWhenInUseAuthorization()
manager.stopUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if let location = locations.first {
manager.stopUpdatingLocation()
render(location)
}
}
func render(_ location: CLLocation) {
let coordinate = CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)
let span = MKCoordinateSpan(latitudeDelta: 0.1, longitudeDelta: 0.1)
let region = MKCoordinateRegion(center: coordinate, span: span)
mapView.setRegion(region, animated: true)
let pin = MKPointAnnotation()
pin.coordinate = coordinate
mapView.addAnnotation(pin)
}
}
Here is the screenshot of Info Plist
Here is the screenshot shot when I run the app..
CodePudding user response:
Try this way: conform your ViewController class to CLLocationManagerDelegate and MKMapViewDelegate, declare your objects:
let mapView = MKMapView()
let manager = CLLocationManager()
in viewDidLoad present mapView and add constraints:
override func viewDidLoad() {
super.viewDidLoad()
mapView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(mapView)
mapView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
mapView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
mapView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
mapView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
}
in viewDidAppear call requestAlwaysAuthorization and requestWhenInUseAuthorization and map configuration
manager.requestAlwaysAuthorization()
manager.requestWhenInUseAuthorization()
if CLLocationManager.locationServicesEnabled() {
manager.delegate = self
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.startUpdatingLocation()
}
mapView.delegate = self
mapView.mapType = .standard
mapView.isZoomEnabled = true
mapView.isScrollEnabled = true
mapView.showsUserLocation = false // if you want to show default pin set to true
if let coor = mapView.userLocation.location?.coordinate{
mapView.setCenter(coor, animated: true)
}
After that set didUpdateLocations
func locationManager(_ manager: CLLocationManager, didUpdateLocations
locations: [CLLocation]) {
guard let mylocation = manager.location else { return }
let myCoordinates: CLLocationCoordinate2D = mylocation.coordinate
mapView.mapType = MKMapType.standard
let span = MKCoordinateSpan(latitudeDelta: 0.1, longitudeDelta: 0.1)
let region = MKCoordinateRegion(center: myCoordinates, span: span)
mapView.setRegion(region, animated: true)
// comment pin object if showsUserLocation = true
let pin = MKPointAnnotation()
pin.coordinate = myCoordinates
pin.title = "You are here"
mapView.addAnnotation(pin)
}
my info.plist Privacy authorizations
The result, I set Tokyo on my simulator options scheme
intere code with your DispatchQueue request in comments below:
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {
let mapView = MKMapView()
let manager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
mapView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(mapView)
mapView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
mapView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
mapView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
mapView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
manager.requestAlwaysAuthorization()
manager.requestWhenInUseAuthorization()
if CLLocationManager.locationServicesEnabled() {
DispatchQueue.main.async {
self.manager.delegate = self
self.manager.desiredAccuracy = kCLLocationAccuracyBest
self.manager.startUpdatingLocation()
self.mapView.delegate = self
self.mapView.mapType = .standard
self.mapView.isZoomEnabled = true
self.mapView.isScrollEnabled = true
self.mapView.showsUserLocation = false // if you want to show default pin
}
}
if let coor = mapView.userLocation.location?.coordinate {
mapView.setCenter(coor, animated: true)
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations
locations: [CLLocation]) {
guard let mylocation = manager.location else { return }
let myCoordinates: CLLocationCoordinate2D = mylocation.coordinate
mapView.mapType = MKMapType.standard
let span = MKCoordinateSpan(latitudeDelta: 0.1, longitudeDelta: 0.1)
let region = MKCoordinateRegion(center: myCoordinates, span: span)
mapView.setRegion(region, animated: true)
let pin = MKPointAnnotation()
pin.coordinate = myCoordinates
pin.title = "You are here"
mapView.addAnnotation(pin)
}
}