Not able to show annotation pin on MKMapview Swift - ios

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.

Related

How to show location on map view on swift? I believe my code is current but simulator doesn't show location or the blue dot?

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)
}

Why userLocation returns (-180.0,-180.0) coordinates on Mapbox?

I use Mapbox with Swift 4 and I have a problem when I want to display the user location. I don't understand why the user location is not set as it should be.
I would get the user location coordinates in the viewDidLoad() method. To do so, I have set MGLMapViewDelegate and CLLocationManagerDelegate in my ViewController declaration. Then, in my viewDidLoad() I have:
// Mapview configuration
let mapView = MGLMapView(frame: self.mapView.bounds)
mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
mapView.showsUserLocation = true
mapView.setUserTrackingMode(.follow, animated: true)
mapView.delegate = self
self.mapView.addSubview(mapView)
// User location
print("User location:")
print(mapView.userLocation!.coordinate)
But I get this:
CLLocationCoordinate2D(latitude: -180.0, longitude: -180.0)
I think it is because the location is not set when the view loads, but I need to get values in viewDidLoad().
What should I do, and why the line mapView.userLocation!.coordinate doesn't work?
EDIT
In fact, I want to use MapboxDirections to display on the map a line between the user location and a fixed point. To do it, I use this code (see the first comment):
let waypoints = [
// HERE I would use the user location coordinates for my first Waypoint
Waypoint(coordinate: CLLocationCoordinate2D(latitude: 38.9131752, longitude: -77.0324047), name: "Mapbox"),
Waypoint(coordinate: CLLocationCoordinate2D(latitude: 38.8977, longitude: -77.0365), name: "White House"),
]
let options = RouteOptions(waypoints: waypoints, profileIdentifier: .automobileAvoidingTraffic)
options.includesSteps = true
_ = directions.calculate(options) { (waypoints, routes, error) in
guard error == nil else {
print("Error calculating directions: \(error!)")
return
}
if let route = routes?.first, let leg = route.legs.first {
print("Route via \(leg):")
let distanceFormatter = LengthFormatter()
let formattedDistance = distanceFormatter.string(fromMeters: route.distance)
let travelTimeFormatter = DateComponentsFormatter()
travelTimeFormatter.unitsStyle = .short
let formattedTravelTime = travelTimeFormatter.string(from: route.expectedTravelTime)
print("Distance: \(formattedDistance); ETA: \(formattedTravelTime!)")
if route.coordinateCount > 0 {
// Convert the route’s coordinates into a polyline.
var routeCoordinates = route.coordinates!
let routeLine = MGLPolyline(coordinates: &routeCoordinates, count: route.coordinateCount)
// Add the polyline to the map and fit the viewport to the polyline.
mapView.addAnnotation(routeLine)
mapView.setVisibleCoordinates(&routeCoordinates, count: route.coordinateCount, edgePadding: .zero, animated: true)
}
}
}
Larme is correct: the user's location typically isn't available yet in -viewDidLoad. Use the -mapView:didUpdateUserLocation: delegate method to be notified when the user's location becomes available and when it updates.
If you need the user’s location before a map is shown, consider running your own CLLocationManager.
-180, -180 is the kCLLocationCoordinate2DInvalid constant from Core Location. You should typically check if CLLocationCoordinate2DIsValid() before trying to display CLLocationCoordinate2D on a map.
Sergey Kargopolov has a great example of how to obtain the user location using CLLocationManager and CLLocationManagerDelegate. Here is his code:
class ViewController: UIViewController, CLLocationManagerDelegate {
var locationManager:CLLocationManager!
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
determineMyCurrentLocation()
}
func determineMyCurrentLocation() {
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestAlwaysAuthorization()
if CLLocationManager.locationServicesEnabled() {
locationManager.startUpdatingLocation()
//locationManager.startUpdatingHeading()
}
}
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()
print("user latitude = \(userLocation.coordinate.latitude)")
print("user longitude = \(userLocation.coordinate.longitude)")
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error)
{
print("Error \(error)")
}
}

MapKit View not zooming in to users location

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
}
}

Current Location in Google Maps with swift

I'm trying to display the user's current location on a google map but in the case below, the map doesn't even get displayed. What should I change to fix this?
var locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
//user location stuff
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation()
}
func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
print("Error" + error.description)
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let userLocation = locations.last
let center = CLLocationCoordinate2D(latitude: userLocation!.coordinate.latitude, longitude: userLocation!.coordinate.longitude)
let camera = GMSCameraPosition.cameraWithLatitude(userLocation!.coordinate.latitude,
longitude: userLocation!.coordinate.longitude, zoom: 8)
let mapView = GMSMapView.mapWithFrame(CGRectZero, camera: camera)
mapView.myLocationEnabled = true
self.view = mapView
let marker = GMSMarker()
marker.position = center
marker.title = "Current Location"
marker.snippet = "XXX"
marker.map = mapView
locationManager.stopUpdatingLocation()
}
You can try this bellow code its working fine
import UIKit
import GoogleMaps
import GooglePlaces
class SearchMapsViewController: UIViewController,
UINavigationBarDelegate, GMSAutocompleteFetcherDelegate,
LocateOnTheMap, UISearchBarDelegate, CLLocationManagerDelegate
{
#IBOutlet var googleMapsContainerView: UIView!
var searchResultController: SearchResultsController!
var resultsArray = [String]()
var googleMapsView:GMSMapView!
var gmsFetcher: GMSAutocompleteFetcher!
var locationManager = CLLocationManager()
override func viewDidAppear(animated: Bool) {
locationManager.delegate = self
locationManager.requestWhenInUseAuthorization()
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation()
self.googleMapsView = GMSMapView (frame: self.googleMapsContainerView.frame)
self.googleMapsView.settings.compassButton = true
self.googleMapsView.myLocationEnabled = true
self.googleMapsView.settings.myLocationButton = true
self.view.addSubview(self.googleMapsView)
searchResultController = SearchResultsController()
searchResultController.delegate = self
gmsFetcher = GMSAutocompleteFetcher()
gmsFetcher.delegate = self
}
func locationManager(manager: CLLocationManager, didFailWithError error: NSError)
{
print("Error" + error.description)
}
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
{
let userLocation = locations.last
let center = CLLocationCoordinate2D(latitude: userLocation!.coordinate.latitude, longitude: userLocation!.coordinate.longitude)
let camera = GMSCameraPosition.cameraWithLatitude(userLocation!.coordinate.latitude, longitude: userLocation!.coordinate.longitude, zoom: 15);
self.googleMapsView.camera = camera
self.googleMapsView.myLocationEnabled = true
let marker = GMSMarker(position: center)
print("Latitude :- \(userLocation!.coordinate.latitude)")
print("Longitude :-\(userLocation!.coordinate.longitude)")
marker.map = self.googleMapsView
marker.title = "Current Location"
locationManager.stopUpdatingLocation()
}
do requier setting on infoPlist and then try this
#IBOutlet weak var your "name of view which show map": GMSMapView!
override func viewDidLoad(){
super.viewDidLoad()
placesClient = GMSPlacesClient.shared()
locationManager.requestAlwaysAuthorization()
if CLLocationManager.locationServicesEnabled(){
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyKilometer
locationManager.distanceFilter = 500
locationManager.requestWhenInUseAuthorization()
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
}
mapView.settings.myLocationButton = true
mapView.settings.zoomGestures = true
mapView.animate(toViewingAngle: 45)
mapView.delegate = self }
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let newLocation = locations.last // find your device location
mapView.camera = GMSCameraPosition.camera(withTarget: newLocation!.coordinate, zoom: 14.0) // show your device location on map
mapView.settings.myLocationButton = true // show current location button
var lat = (newLocation?.coordinate.latitude)! // get current location latitude
var long = (newLocation?.coordinate.longitude)! //get current location longitude
}
The problem is that you are setting the mapView's frame to CGRectZero. This causes the map to have zero height and zero width, no wonder it does not show!
Try setting it to CGRectMake(0,0,200,200) for example, this will give you a map at the left top of the screen with a size of 200 x 200.
I have never used Swift before, so the syntax might be a little different for CGRectMake()
It seems that your creation of the map isn't in your viewDidLoad function. You may want to try moving that there and see what happens.
Add the appropriate properties into the info.plist.
You should put make sure you have the NS properties of locationalwaysusagedescription and wheninuseusagedescription in the information properties list. This allows for the permissions of the current location to be asked.
import UIKit
import GoogleMaps
import GooglePlaces
import CoreLocation
class MapsViewController: UIViewController, CLLocationManagerDelegate, GMSMapViewDelegate {
var mapView = GMSMapView()
var locationManager = CLLocationManager()
let marker = GMSMarker()
override func viewDidLoad(){
super.viewDidLoad()
mapView.frame = self.view.bounds
self.view.addSubview(mapView)
locationManager.requestAlwaysAuthorization()
if CLLocationManager.locationServicesEnabled(){
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.distanceFilter = 10
locationManager.requestWhenInUseAuthorization()
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
}
mapView.settings.myLocationButton = true
mapView.settings.zoomGestures = true
mapView.animate(toViewingAngle: 45)
mapView.delegate = self
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let newLocation = locations.last // find your device location
mapView.camera = GMSCameraPosition.camera(withTarget: newLocation!.coordinate, zoom: 14.0) // show your device location on map
mapView.settings.myLocationButton = true // show current location button
let lat = (newLocation?.coordinate.latitude)! // get current location latitude
let long = (newLocation?.coordinate.longitude)! //get current location longitude
marker.position = CLLocationCoordinate2DMake(lat,long)
marker.map = mapView
print("Current Lat Long - " ,lat, long )
}
func mapView(_ mapView: GMSMapView, didTapAt coordinate: CLLocationCoordinate2D) {
mapView.clear()
DispatchQueue.main.async {
let position = CLLocationCoordinate2D(latitude: coordinate.latitude, longitude: coordinate.longitude)
self.marker.position = position
self.marker.map = mapView
self.marker.icon = UIImage(named: "default_marker")
print("New Marker Lat Long - ",coordinate.latitude, coordinate.longitude)
}
}
}

Show Current Location and Update Location in MKMapView in Swift

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)
}

Resources