In my application I have a MKMapKit view and when my application starts, if the user allows location services, I want the Map to zoom into the user's location. The code I wrote is:
override func viewDidLoad() {
super.viewDidLoad()
mapKitView.delegate = self
mapKitView.showsUserLocation = true
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.delegate = self
if (CLLocationManager.locationServicesEnabled()) {
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestAlwaysAuthorization()
locationManager.requestWhenInUseAuthorization()
}
locationManager.requestWhenInUseAuthorization()
if CLLocationManager.locationServicesEnabled() {
locationManager.startUpdatingLocation()
}
DispatchQueue.main.async {
self.locationManager.startUpdatingLocation()
}
}
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
let noLocation = CLLocationCoordinate2D()
let viewRegion = MKCoordinateRegionMakeWithDistance(noLocation, 200, 200)
mapKitView.setRegion(viewRegion, animated: false)
}
In my app, it shows the users location, but does not animate and zoom in.
Use the user's location to calculate the view region and change the animated parameter to true:
if let location = mapKitView.userLocation.location {
let viewRegion = MKCoordinateRegionMakeWithDistance(location, 200, 200)
mapKitView.setRegion(viewRegion, animated: true)
}
In Swift 3.0, try my code in your didUpdateLocation method.
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
{
//get location cordinate
let locValue:CLLocationCoordinate2D = manager.location!.coordinate
print(locValue)
//set updating location stop
locationManager.stopUpdatingLocation()
let location = locations.last! as CLLocation//create object of CLLocation
//get location cordinate
let center = CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)
//set map zooming using region
let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01))
self.mapView.setRegion(region, animated: true)
}
I hope it's work #Rahul Bir
In Swift 3.0 you should use this code if you want to zoom map Kit on the starting view of the map view.
var zoomIn = false
var zoomAnnotation:MKAnnotation
func mapView(mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
if let annotation = zoomAnnotation where zoomIn == true {
let region = MKCoordinateRegion(center: zoomAnnotation.coordinate, span: MKCoordinateSpan(latitudeDelta: 0.075, longitudeDelta: 0.075))
mapView.setRegion(region, animated: true)
zoomIn = false
}
}
Related
I am trying to show on my current location and a blue dot on the map using the map view on swift. However it does not show my location nor the blue dot I'm very positive of my code but I can't get it to show! it's probably an issue with the settings?
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController {
#IBOutlet weak var mapView: MKMapView!
let locationManager = CLLocationManager()
let regionInMeters: Double = 1000
override func viewDidLoad() {
super.viewDidLoad()
checkLocationServices()
}
func setupLocationManager() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
}
func centerViewOnUserLocation() {
if let location = locationManager.location?.coordinate {
let region = MKCoordinateRegion.init(center: location, latitudinalMeters: regionInMeters, longitudinalMeters: regionInMeters)
mapView.setRegion(region, animated: true)
}
}
func checkLocationServices() {
if CLLocationManager.locationServicesEnabled() {
setupLocationManager()
checkLocationAuthorrization()
} else {
// Show alert letting the user know they have to turn this on.
}
}
func checkLocationAuthorrization() {
switch CLLocationManager.authorizationStatus() {
case .authorizedWhenInUse:
mapView.showsUserLocation = true
centerViewOnUserLocation()
locationManager.startUpdatingLocation()
break
case .denied:
// Show alret instructing them how to turn on permissions
break
case .notDetermined:
break
case .restricted:
// Show alret letting them know what's up
break
case .authorizedAlways:
break
}
}
}
extension ViewController: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let location = locations.last else { return }
let center = CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)
let region = MKCoordinateRegion.init(center: center, latitudinalMeters: regionInMeters, longitudinalMeters: regionInMeters)
mapView.setRegion(region, animated: true)
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
checkLocationAuthorrization()
}
}
You have to add below permission in Info.plist file
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Usage Description</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>Usage Description</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Usage Description</string>
Import libraries:
import MapKit
import CoreLocation
Set delegates:
CLLocationManagerDelegate,MKMapViewDelegate
Add variable:
private var locationManager: CLLocationManager!
private var currentLocation: CLLocation?
write below code on viewDidLoad():
mapView.delegate = self
mapView.showsUserLocation = true
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
// Check for Location Services
if CLLocationManager.locationServicesEnabled() {
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
}
Write delegate method for location:
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
defer { currentLocation = locations.last }
if currentLocation == nil {
// Zoom to user location
if let userLocation = locations.last {
let viewRegion = MKCoordinateRegion(center: userLocation.coordinate, latitudinalMeters: 2000, longitudinalMeters: 2000)
mapView.setRegion(viewRegion, animated: false)
}
}
}
Thats all, Now you able to see your current location and blue dot.
To show user location on map do following steps:
try this path-
Go to product->Edit Scheme->Options->select Allow Location simulation and select default location.
Here You can also add custom location using GPX file.
After setting clean and run the app.
The problem seems to be in method checkLocationAuthorrization, here you have to ask for locationManager.requestWhenInUseAuthorization() when the status is notDetermined, like so:
func checkLocationAuthorization(authorizationStatus: CLAuthorizationStatus? = nil) {
switch (authorizationStatus ?? CLLocationManager.authorizationStatus()) {
case .authorizedAlways, .authorizedWhenInUse:
locationManager.startUpdatingLocation()
mapView.showsUserLocation = true
case .restricted, .denied:
// show alert instructing how to turn on permissions
print("Location Servies: Denied / Restricted")
case .notDetermined:
locationManager.requestWhenInUseAuthorization()
}
}
Also change the delegate method to pass the current status received
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
self.checkLocationAuthorization(authorizationStatus: status)
}
Also note that locationManager.requestWhenInUseAuthorization() will not work, if Info.plist does not have following usage description(s), so edit the Info.plist file and make sure:
<key>NSLocationAlwaysAndWhenInUseUsageDescription</key>
<string>Message for AlwaysAndWhenInUseUsageDescription</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>Message for AlwaysUsageDescription</string>
<key>NSLocationWhenInUseUsageDescription</key>
<string>Message for WhenInUseUsageDescription</string>
Finally, you got to wait for an location update to call centerViewOnUserLocation, like so
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let location = locations.last else { return }
let span = MKCoordinateSpan(latitudeDelta: 0.05, longitudeDelta: 0.05)
let region = MKCoordinateRegion(center: location.coordinate, span: span)
mapView.setRegion(region, animated: true)
}
Simulator doesn't show current location but you can manually add a location in it by:
Debug -> Location -> Custom Location and then give coordinates.
In your viewDidLoad method please write the below code.
Default value of showsUserLocation is false. So, we have to update it's default value.
override func viewDidLoad() {
super.viewDidLoad()
self.mapView.showsUserLocation = true
checkLocationServices()
}
Refer my updated code.
import UIKit
import MapKit
class ViewController: UIViewController {
#IBOutlet weak var mapview: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
let location = CLLocationCoordinate2D(latitude: "", longitude: "")
let span = MKCoordinateSpanMake(0.5, 0.5)
let region = MKCoordinateRegion(center: location, span: span)
mapview.setRegion(region, animated: true)
let annotation = MKPointAnnotation()
annotation.coordinate = location
annotation.title = "your title"
mapview.addAnnotation(annotation)
}
When I was using let viewRegion = MKCoordinateRegionMakeWithDistance((userLocation?.coordinate)!, 600, 600) it was fine, however apparently Swift has now replaced this with
let viewRegion = MKCoordinateRegion(center: (userLocation?.coordinate)!, latitudinalMeters: 600, longitudinalMeters: 600)
My location no longer appears on the map anymore, the map shows the right area. Here is my code.
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let locValue:CLLocationCoordinate2D = manager.location!.coordinate
print("locations = \(locValue.latitude) \(locValue.longitude)")
let userLocation = locations.last
let viewRegion = MKCoordinateRegion(center: (userLocation?.coordinate)!, latitudinalMeters: 600, longitudinalMeters: 600)
self.map.setRegion(viewRegion, animated: true)
}
first hope you didn't forget to extends your viewcontroller from CLLocationManagerDelegate and MKMapViewDelegate.
you can access the userlocation directly from locationManager variable private let locationManager: CLLocationManager = CLLocationManager() from anywhere in your class by calling
userLocation = self.locationManager.location
also don't forget to delegate your view controller to location manager and mapview :
locationManager.delegate = self
mapView.delegate = self
I am trying to show annotation pin for current location. For that I have written following code
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
mapView.layer.cornerRadius = 8.0
imageView.layer.cornerRadius = 8.0
//mapview settings
mapView.mapType = MKMapType.standard
mapView.isZoomEnabled = true
mapView.isZoomEnabled = true
// Or, if needed, we can position map in the center of the view
mapView.center = view.center
mapView.delegate = self
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
determineCurrentLocation()
}
func determineCurrentLocation()
{
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestAlwaysAuthorization()
if CLLocationManager.locationServicesEnabled() {
//locationManager.startUpdatingHeading()
locationManager.startUpdatingLocation()
}
}
//Mapview Delegate methods
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let userLocation:CLLocation = locations[0] as CLLocation
// Call stopUpdatingLocation() to stop listening for location updates,
// other wise this function will be called every time when user location changes.
//manager.stopUpdatingLocation()
let center = CLLocationCoordinate2D(latitude: userLocation.coordinate.latitude, longitude: userLocation.coordinate.longitude)
let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01))
mapView.setRegion(region, animated: true)
// Drop a pin at user's Current Location
let myAnnotation: MKPointAnnotation = MKPointAnnotation()
myAnnotation.coordinate = CLLocationCoordinate2DMake(userLocation.coordinate.latitude, userLocation.coordinate.longitude);
myAnnotation.title = "Current location"
mapView.addAnnotation(myAnnotation)
}
func locationManager(manager: CLLocationManager, didFailWithError error: Error)
{
print("Error \(error)")
}
But, its nothing showing in mapview. Any suggestions?
You need to add NSLocationAlwaysUsageDescription key in Info.plist with a message to be displayed in the prompt.
I am trying to simply show user's location on the map, but I need to when app launches, the map should zoom to current location ,but I don't know why map doesn't zoom at all and it's like this :
Here is the code :
class MapViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {
#IBOutlet weak var mapView: MKMapView!
var locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
mapView.delegate = self
mapView.showsUserLocation = true
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.delegate = self
DispatchQueue.main.async {
self.locationManager.startUpdatingLocation()
}
}
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
let location = locations.last as! CLLocation
let center = CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)
var region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.1, longitudeDelta: 0.1))
region.center = mapView.userLocation.coordinate
mapView.setRegion(region, animated: true)
}
I faced similar issue and wasted 4 days thinking whats going wrong. Finally resolved with creating these lines of code in viewDidLoad Method :
//Zoom to user location
let noLocation = CLLocationCoordinate2D()
let viewRegion = MKCoordinateRegionMakeWithDistance(noLocation, 200, 200)
mapView.setRegion(viewRegion, animated: false)
mapView.showsUserLocation = true
In ViewDidLoad Method add these new changes code :
override func viewDidLoad() {
super.viewDidLoad()
let locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
// Check for Location Services
if (CLLocationManager.locationServicesEnabled()) {
locationManager.requestAlwaysAuthorization()
locationManager.requestWhenInUseAuthorization()
}
//Zoom to user location
if let userLocation = locationManager.location?.coordinate {
let viewRegion = MKCoordinateRegionMakeWithDistance(userLocation, 200, 200)
mapView.setRegion(viewRegion, animated: false)
}
self.locationManager = locationManager
DispatchQueue.main.async {
self.locationManager.startUpdatingLocation()
}
}
Hope this helps to resolve your issue. Feel free to post comment if any further issue. Thanks
Here's another approach for Swift 3, XCode 8.2. First, write out a helper function:
let homeLocation = CLLocation(latitude: 37.6213, longitude: -122.3790)
let regionRadius: CLLocationDistance = 200
func centerMapOnLocation(location: CLLocation)
{
let coordinateRegion = MKCoordinateRegionMakeWithDistance(location.coordinate,
regionRadius * 2.0, regionRadius * 2.0)
mapView.setRegion(coordinateRegion, animated: true)
}
Then, call in in viewDidLoad()
mapView.showsUserLocation = true
centerMapOnLocation(location: homeLocation)
This will start the app with the location specified in the variable zoomed in.
In Swift 4.2 there has been changes with this code. Here is how it works now:
import UIKit
import MapKit
import CoreLocation
class MapVC: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {
#IBOutlet weak var mapView: MKMapView!
var locationManager = CLLocationManager()
let authorizationStatus = CLLocationManager.authorizationStatus()
let regionRadius: Double = 1000
override func viewDidLoad() {
super.viewDidLoad()
mapView.delegate = self
locationManager.delegate = self
configureLocationServices()
}
func centerMapOnUserLocation() {
guard let coordinate = locationManager.location?.coordinate else {return}
let coordinateRegion = MKCoordinateRegion(center: coordinate, latitudinalMeters: regionRadius, longitudinalMeters: regionRadius)
mapView.setRegion(coordinateRegion, animated: true)
}
func configureLocationServices() {
if authorizationStatus == .notDetermined {
locationManager.requestAlwaysAuthorization()
} else {
return
}
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
centerMapOnUserLocation()
}
}
Code:
import UIKit
import MapKit
class ViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {
#IBOutlet weak var mapview: MKMapView!
let locationmanager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
mapview.mapType = MKMapType.standard
let location = CLLocationCoordinate2DMake(22.4651, 70.0771)
let span = MKCoordinateSpanMake(0.5, 0.5)
let region = MKCoordinateRegionMake(location, span)
mapview.setRegion(region, animated: true)
let annonation = MKPointAnnotation()
annonation.coordinate = location
annonation.title = "Chandi Bazar"
annonation.subtitle = "Jamnagar"
//
mapview.addAnnotation(annonation)
self.locationmanager.requestWhenInUseAuthorization()
if CLLocationManager.locationServicesEnabled()
{
locationmanager.delegate = self
locationmanager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationmanager.startUpdatingLocation()
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
{
let locValue:CLLocationCoordinate2D = manager.location!.coordinate
print("locations = \(locValue.latitude) \(locValue.longitude)")
locationmanager.stopUpdatingLocation()
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView?
{
if (annotation is MKUserLocation)
{
return nil
}
let annotationidentifier = "Annotationidentifier"
var annotationview:MKAnnotationView
annotationview = MKAnnotationView(annotation: annotation, reuseIdentifier: annotationidentifier)
let btn = UIButton(type: .detailDisclosure)
btn.addTarget(self, action: #selector(ViewController.hirenagravat(sender:)), for: .touchUpInside)
annotationview.rightCalloutAccessoryView = btn
annotationview.image = UIImage(named: "images (4).jpeg")
annotationview.canShowCallout = true
return annotationview
}
func hirenagravat(sender:UIButton)
{
let fvc = storyboard?.instantiateViewController(withIdentifier: "secondViewController") as? secondViewController
self.navigationController?.pushViewController(fvc!, animated: true)
}
In swift 4.1. To change the Zoom level you need to change the span value i.e MKCoordinateSpan(latitudeDelta: 0.95, longitudeDelta: 0.95)
let lat = "33.847105"
let long = "-118.2673272"
let region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: Double(lat)!, longitude: Double(long)!), span: MKCoordinateSpan(latitudeDelta: 0.95, longitudeDelta: 0.95))
DispatchQueue.main.async {
self.mapView.setRegion(region, animated: true)
}
Swift 5.0
let span = MKCoordinateSpan.init(latitudeDelta: 0.01, longitudeDelta:
0.01)
let coordinate = CLLocationCoordinate2D.init(latitude: 21.282778, longitude: -157.829444) // provide you lat and long
let region = MKCoordinateRegion.init(center: coordinate, span: span)
mapView.setRegion(region, animated: true)
when you set region -> you cannot zoom the map anymore. below to fix that
func yourFuncName() {
//this is global var
regionHasBeenCentered = false
if !self.regionHasBeenCentered {
let span: MKCoordinateSpan = MKCoordinateSpanMake(0.01, 0.01)
let userLocation: CLLocationCoordinate2D = CLLocationCoordinate2DMake(_cllocationOfUserCurrentLocation!.coordinate.latitude, _cllocationOfUserCurrentLocation!.coordinate.longitude)
let region: MKCoordinateRegion = MKCoordinateRegionMake(userLocation, span)
self.mapView.setRegion(region, animated: true)
self.regionHasBeenCentered = true
}
self.mapView.showsUserLocation = true
}
Try with MKMapViewDelegate func:
var isInitiallyZoomedToUserLocation: Bool = false
func mapView(_ mapView: MKMapView, didUpdate userLocation: MKUserLocation) {
if !isInitiallyZoomedToUserLocation {
isInitiallyZoomedToUserLocation = true
mapView.showAnnotations([userLocation], animated: true)
}
}
func animateToUserLocation() {
if let annoation = mapView.annotations.filter ({ $0 is MKUserLocation }).first {
let coordinate = annoation.coordinate
let viewRegion = MKCoordinateRegion(center: coordinate, latitudinalMeters: 200, longitudinalMeters: 200)
mapView.setRegion(viewRegion, animated: true)
}
}
I am learning how to use the new Swift language (only Swift, no Objective-C). To do it, I want to do a simple view with a map (MKMapView). I want to find and update the location of the user (like in the Apple Map app).
I tried this, but nothing happened:
import MapKit
import CoreLocation
class MapView : UIViewController, CLLocationManagerDelegate {
#IBOutlet weak var map: MKMapView!
var locationManager: CLLocationManager!
override func viewDidLoad() {
super.viewDidLoad()
if (CLLocationManager.locationServicesEnabled())
{
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
}
}
}
Could you please help me?
You have to override CLLocationManager.didUpdateLocations (part of CLLocationManagerDelegate) to get notified when the location manager retrieves the current location:
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if let location = locations.last{
let center = CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)
let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01))
self.map.setRegion(region, animated: true)
}
}
NOTE: If your target is iOS 8 or above, you must include the NSLocationAlwaysUsageDescription or NSLocationWhenInUseUsageDescription key in your Info.plist to get the location services to work.
100% working, easy steps and tested
Import libraries:
import MapKit
import CoreLocation
set delegates:
CLLocationManagerDelegate,MKMapViewDelegate
Take variable:
let locationManager = CLLocationManager()
write this code on viewDidLoad():
self.locationManager.requestAlwaysAuthorization()
// For use in foreground
self.locationManager.requestWhenInUseAuthorization()
if CLLocationManager.locationServicesEnabled() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation()
}
mapView.delegate = self
mapView.mapType = .standard
mapView.isZoomEnabled = true
mapView.isScrollEnabled = true
if let coor = mapView.userLocation.location?.coordinate{
mapView.setCenter(coor, animated: true)
}
Write delegate method for location:
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let locValue:CLLocationCoordinate2D = manager.location!.coordinate
mapView.mapType = MKMapType.standard
let span = MKCoordinateSpanMake(0.05, 0.05)
let region = MKCoordinateRegion(center: locValue, span: span)
mapView.setRegion(region, animated: true)
let annotation = MKPointAnnotation()
annotation.coordinate = locValue
annotation.title = "Javed Multani"
annotation.subtitle = "current location"
mapView.addAnnotation(annotation)
//centerMap(locValue)
}
Do not forgot to set permission in info.plist
<key>NSLocationWhenInUseUsageDescription</key>
<string>This application requires location services to work</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>This application requires location services to work</string>
It's look like:
For swift 3 and XCode 8 I find this answer:
First, you need set privacy into info.plist. Insert string NSLocationWhenInUseUsageDescription with your description why you want get user location. For example, set string "For map in application".
Second, use this code example
#IBOutlet weak var mapView: MKMapView!
private var locationManager: CLLocationManager!
private var currentLocation: CLLocation?
override func viewDidLoad() {
super.viewDidLoad()
mapView.delegate = self
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
// Check for Location Services
if CLLocationManager.locationServicesEnabled() {
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
}
}
// MARK - CLLocationManagerDelegate
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
defer { currentLocation = locations.last }
if currentLocation == nil {
// Zoom to user location
if let userLocation = locations.last {
let viewRegion = MKCoordinateRegionMakeWithDistance(userLocation.coordinate, 2000, 2000)
mapView.setRegion(viewRegion, animated: false)
}
}
}
Third, set User Location flag in storyboard for mapView.
MyLocation
is a Swift iOS Demo.
You can use this demo for the following:
Show the current location.
Choose other location: in this case stop tracking the location.
Add a push pin to a MKMapView(iOS) when touching.
Hi Sometimes setting the showsUserLocation in code doesn't work for some weird reason.
So try a combination of the following.
In viewDidLoad()
self.mapView.showsUserLocation = true
Go to your storyboard in Xcode, on the right panel's attribute inspector tick the User location check box, like in the attached image. run your app and you should be able to see the User location
Swift 5.1
Get Current Location and Set on MKMapView
Import libraries:
import MapKit
import CoreLocation
set delegates:
CLLocationManagerDelegate , MKMapViewDelegate
Declare variable:
let locationManager = CLLocationManager()
Write this code on viewDidLoad():
self.locationManager.requestAlwaysAuthorization()
self.locationManager.requestWhenInUseAuthorization()
if CLLocationManager.locationServicesEnabled() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation()
}
mapView.delegate = self
mapView.mapType = .standard
mapView.isZoomEnabled = true
mapView.isScrollEnabled = true
if let coor = mapView.userLocation.location?.coordinate{
mapView.setCenter(coor, animated: true)
}
Write delegate method for location:
func locationManager(_ manager: CLLocationManager, didUpdateLocations
locations: [CLLocation]) {
let locValue:CLLocationCoordinate2D = manager.location!.coordinate
mapView.mapType = MKMapType.standard
let span = MKCoordinateSpan(latitudeDelta: 0.05, longitudeDelta: 0.05)
let region = MKCoordinateRegion(center: locValue, span: span)
mapView.setRegion(region, animated: true)
let annotation = MKPointAnnotation()
annotation.coordinate = locValue
annotation.title = "You are Here"
mapView.addAnnotation(annotation)
}
Set permission in info.plist *
<key>NSLocationWhenInUseUsageDescription</key>
<string>This application requires location services to work</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>This application requires location services to work</string>
For Swift 2, you should change it to the following:
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations.last
let center = CLLocationCoordinate2D(latitude: location!.coordinate.latitude, longitude: location!.coordinate.longitude)
let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01))
self.map.setRegion(region, animated: true)
}
You just need to set the userTrackingMode of the MKMapView. If you only want to display and track the user location and implement the same behaviour as the Apple Maps app uses, there is no reason for writing additional code.
mapView.userTrackingMode = .follow
See more at https://developer.apple.com/documentation/mapkit/mkmapview/1616208-usertrackingmode .
you have to override CLLocationManager.didUpdateLocations
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let userLocation:CLLocation = locations[0] as CLLocation
locationManager.stopUpdatingLocation()
let location = CLLocationCoordinate2D(latitude: userLocation.coordinate.latitude, longitude: userLocation.coordinate.longitude)
let span = MKCoordinateSpanMake(0.5, 0.5)
let region = MKCoordinateRegion (center: location,span: span)
mapView.setRegion(region, animated: true)
}
you also have to add NSLocationWhenInUseUsageDescription and NSLocationAlwaysUsageDescription to your plist setting Result as value
In Swift 4, I had used the locationManager delegate function as defined above ..
func locationManager(manager: CLLocationManager!,
didUpdateLocations locations: [AnyObject]!) {
.. but this needed to be changed to ..
func locationManager(_ manager: CLLocationManager,
didUpdateLocations locations: [CLLocation]) {
This came from .. https://github.com/lotfyahmed/MyLocation/blob/master/MyLocation/ViewController.swift - thanks!
mapView.showsUserLocation = true
Create UIButton and add this action
#IBAction func showCurrentLocation(_ sender: Any) {
let coordinate = mapView.userLocation.coordinate
let center = CLLocationCoordinate2D(latitude: coordinate.latitude, longitude: coordinate.longitude)
let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01))
self.mapView.setRegion(region, animated: true)
}