Swift MapKit Overlays will not Show on Map - swift

I am trying to display any overlay on the map. I have followed many many tutorials but nothing works. The map will always load with no errors but the overlay will never show on the map.
I am trying to get this , an inverted circle, to show on the map.
import Foundation
import UIKit
import MapKit
class MKInvertedCircleOverlayRenderer: MKOverlayRenderer {
var fillColor: UIColor = UIColor.red
var strokeColor: UIColor = UIColor.blue
var lineWidth: CGFloat = 3
var circle: MKCircle
init(circle: MKCircle) {
self.circle = circle
super.init(overlay: circle)
}
override func draw(_ mapRect: MKMapRect, zoomScale: MKZoomScale, in context: CGContext) {
let path = UIBezierPath(rect: rect(for: MKMapRect.world))
let excludePath: UIBezierPath = UIBezierPath(roundedRect: CGRect(x: circle.coordinate.latitude, y: circle.coordinate.longitude,
width: circle.boundingMapRect.size.width,
height: circle.boundingMapRect.size.height),
cornerRadius: CGFloat(circle.boundingMapRect.size.width))
context.setFillColor(fillColor.cgColor)
path.append(excludePath)
context.addPath(path.cgPath)
context.fillPath(using: .evenOdd)
context.addPath(excludePath.cgPath)
context.setLineWidth(9 / zoomScale)
context.setStrokeColor(strokeColor.cgColor)
context.strokePath()
//line showing circle radius
let lineBeginPoint = CGPoint(x: excludePath.bounds.midX, y: excludePath.bounds.midY)
let lineEndPoint = CGPoint(x: excludePath.bounds.maxX, y: excludePath.bounds.midY)
let linePath: UIBezierPath = UIBezierPath()
linePath.move(to: lineBeginPoint)
linePath.addLine(to: lineEndPoint)
context.addPath(linePath.cgPath)
context.setLineWidth(6/zoomScale)
context.setStrokeColor(UIColor.black.cgColor)
context.setLineDash(phase: 1, lengths: [20 / zoomScale, 10 / zoomScale])
context.strokePath()
// circle at the end of the line above
let circleSize: CGFloat = 30/zoomScale
let circleRect = CGRect(origin: CGPoint(x: lineEndPoint.x - (circleSize/2), y: lineEndPoint.y - (circleSize/2)),
size: CGSize(width: circleSize, height: circleSize))
let circlePath: UIBezierPath =
UIBezierPath(roundedRect: circleRect, cornerRadius: circleSize)
context.addPath(circlePath.cgPath)
context.setFillColor(UIColor.black.cgColor)
context.fillPath()
}
}
import Foundation
import MapKit
import UIKit
class MKInvertedCircle : NSObject, MKOverlay {
var coordinate: CLLocationCoordinate2D
var boundingMapRect: MKMapRect {
return MKMapRect.world
}
init(center coord: CLLocationCoordinate2D) {
self.coordinate = coord
}
}
viewcontroller
import MapKit
import UIKit
import Foundation
class ViewController: UIViewController, MKMapViewDelegate {
private let locationManager = CLLocationManager()
private var currentCoordinate: CLLocationCoordinate2D?
#IBOutlet weak var mapView: MKMapView!
func addCircleOverlay() {
let overlay = MKInvertedCircle(center: CLLocationCoordinate2D())
mapView.addOverlay(overlay)
}
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
if overlay is MKInvertedCircle {
let circleRenderer = MKInvertedCircleOverlayRenderer(circle: MKCircle())
return circleRenderer
}
else {
return MKOverlayRenderer(overlay: overlay)
}
}
// if screen loads ask for location permissions
override func viewDidLoad() {
super.viewDidLoad()
configureLocationServices()
mapView.delegate = self;
// Do any additional setup after loading the view.
}
//how to ask for location permissions
private func configureLocationServices() {
locationManager.delegate = self
//check location permissions
let status = CLLocationManager.authorizationStatus()
//if location permissions not set, ask
if status == .notDetermined {
locationManager.requestAlwaysAuthorization()
} else if status == .authorizedAlways || status == .authorizedWhenInUse {
//begin tracking location
beginLocationUpdates(locationManager: locationManager)
}
}
//begin tracking location
private func beginLocationUpdates(locationManager: CLLocationManager) {
//show blue dot
mapView.showsUserLocation = true
//track location to best of phones ability
locationManager.desiredAccuracy = kCLLocationAccuracyBest
//start updating location
locationManager.startUpdatingLocation()
}
//zoom to location
private func zoomToLatestLocation(with coordinate: CLLocationCoordinate2D) {
//set zoom level
let zoomRegion = MKCoordinateRegion.init(center: coordinate, latitudinalMeters: 10000, longitudinalMeters: 10000)
//tells map to zoom animated
mapView.setRegion(zoomRegion, animated: true)
}
}
extension ViewController: CLLocationManagerDelegate {
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
print("Did get Latest Location")
guard let latestLocation = locations.first else {return }
if currentCoordinate == nil{
zoomToLatestLocation(with: latestLocation.coordinate)
}
currentCoordinate = latestLocation.coordinate
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
print("The Status Changed")
if status == .authorizedAlways || status == .authorizedWhenInUse {
beginLocationUpdates(locationManager: manager)
}
}
}
But I will settle for any overlay working at all as a step in the right direction.
Does anyone know of up to date code that will display an overlay on the map?
Thanks.

the error seems to be your delegate's
mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer
instead of using the overlay in this function, you're initialising a new MKCircle.
Try this instead
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
if let circle = overlay as? MKCircle {
return MKInvertedCircleOverlayRenderer(circle: circle)
} else {
return MKOverlayRenderer(overlay: overlay)
}
}

Related

Custom infoView for array of markers swift

I have an application where I am working with Googlemaps, I am able to create markers for all the coordinates needed but the issue I am facing now is I want to show a custom UIView when a user taps on a marker to show the info associated with that marker
func showFeaturedProperties(properties: [FeaturedProperties]) {
self.properties = properties
properties.forEach { (props) in
var lat = Double(props.latitude!) as! Double
var lng = Double(props.longitude!) as! Double
let marker = GMSMarker()
marker.position = CLLocationCoordinate2D(latitude: lat,
longitude: lng)
marker.groundAnchor = CGPoint(x: 0.5, y: 0.5)
marker.isFlat = true
marker.map = mapView
if props.typeId == 1 {
marker.icon = #imageLiteral(resourceName: "_map_rent_icon")
} else {
marker.icon = #imageLiteral(resourceName: "_map_buy_icon")
}
marker.setIconSize(scaledToSize: .init(width: 25, height: 25))
marker.iconView?.contentMode = .scaleAspectFit
self.markers.append(marker)
}
}
The above code shows the marker on the map, how can I show Details when the marker is clicked?
I have so far extended the GMSMapViewDelegate
func mapView(_ mapView: GMSMapView, markerInfoContents marker: GMSMarker) -> UIView? {
if let index = markers.index(of: marker) {
let tappedState = properties[index]
log(tappedState.id)
}
let infoView = BaseCardView()
return infoView
}
this does not work still any help is welcomed
Create infowindow marker view with xib file
import UIKit
import GoogleMaps
class InfoMarkerView: UIView {
var view:UIView!
var parentVC:StartRideViewController?
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
setup()
}
func setup() {
view = loadViewFromNib()
view.frame = bounds
view.autoresizingMask = UIViewAutoresizing.flexibleWidth
view.autoresizingMask = UIViewAutoresizing.flexibleHeight
addSubview(view)
}
func loadViewFromNib() -> UIView {
let bundle = Bundle(for:type(of: self))
let nib = UINib(nibName: "InfoMarkerView", bundle: bundle)
let view = nib.instantiate(withOwner: self, options: nil)[0] as! UIView
return view
}
func UpdateView(marker:GMSMarker){
// set values to labels here
}
}
Add GMSMapViewDelegate to your viewcontroller file
var mapView: GMSMapView!
var infoMarkerView:InfoMarkerView?
if(latitude != 0 && longitude != 0){
let position = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
let marker = GMSMarker(position: position)
var myData = Dictionary<String, Any>()
myData["title"] = ridername
myData["snippet"] = ridertime
myData["photoUrl"] = photoUrl
myData["position"] = position
myData["accuracy"] = accuracy
myData["uid"] = riderUID
myData["status"] = riderStatus
marker.userData = myData
marker.title = ridername
marker.snippet = ridertime
marker.position = position
marker.iconView = self.showImageonMap(imgPath:photoUrl)
marker.map = self.mapView
}
// MARK: GMSMapViewDelegate method implementation
func mapView(_ mapView: GMSMapView!, didTapAt coordinate: CLLocationCoordinate2D) {
print("here")
if infoMarkerView != nil {
infoMarkerView?.removeFromSuperview()
}
}
func mapView(_ mapView: GMSMapView, didTap overlay: GMSOverlay)
{
print(overlay.zIndex)
print("User Tapped Layer: \(overlay)")
if infoMarkerView != nil {
infoMarkerView?.removeFromSuperview()
}
}
func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
//let update = GMSCameraUpdate.zoom(by: zoomLevel)
//mapView.animate(with: update)
if infoMarkerView != nil {
infoMarkerView?.removeFromSuperview()
}
infoMarkerView = InfoMarkerView(frame: CGRect(x: marker.infoWindowAnchor.x, y: marker.infoWindowAnchor.y, width:180, height: 120))
infoMarkerView?.parentVC = self
// Offset the info window to be directly above the tapped marker
infoMarkerView?.center = mapView.projection.point(for: marker.position)
infoMarkerView?.center.y = (infoMarkerView?.center.y)! - 125
infoMarkerView?.UpdateView(marker: marker)
mapView.addSubview(infoMarkerView!)
return true
}
func mapView(_ mapView: GMSMapView, didBeginDragging marker: GMSMarker) {
if infoMarkerView != nil {
infoMarkerView?.removeFromSuperview()
}
}
func mapView(_ mapView: GMSMapView, didChange position: GMSCameraPosition) {
if infoMarkerView != nil {
infoMarkerView?.removeFromSuperview()
}
}

How do I add image overlays to an MKMapView?

----------UPDATED------------
original question at the bottom
I've gotten pretty far, and I have this now:
class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
#IBOutlet var mapView: MKMapView!
var locationManager: CLLocationManager!
var mapOverlay: MKOverlay!
override func viewDidLoad() {
super.viewDidLoad()
var points = [CLLocationCoordinate2D(latitude: -29.8122, longitude: 148.6351),
CLLocationCoordinate2D(latitude: -27.9307, longitude: 148.6351),
CLLocationCoordinate2D(latitude: -27.9307, longitude: 150.9909),
CLLocationCoordinate2D(latitude: -29.8122, longitude: 150.9909)]
let tile = MKPolygon(coordinates: &points, count: points.count)
tile.title = "zurich"
mapView.addOverlay(tile)
//Setup our Location Manager
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation()
//Setup our Map View
mapView.delegate = self
mapView.mapType = MKMapType.satellite
mapView.showsUserLocation = true
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// mapView delegate function
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
let renderer = MKPolygonRenderer(overlay: overlay)
renderer.fillColor = UIColor.red
return renderer
}
}
I now need to know how to replace the renderer.fillColor = UIColor.red with something that will display my image.
Thanks once again
----- original question ------
So, I'm new to Swift and MapKit and I want to add a simple image overlay on top of an MKMapView. I've found a few answers, but they're all confusing, and they are all for Swift 3 and earlier.
I've found that a delegate for the map view is needed, is that a file?
I have already created a map view using the main view controller.
This is what I've done so far (this is in the ViewController.swift file):
import UIKit
import MapKit
class ViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate
{
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
}
#IBOutlet weak var mapView: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib
let location = CLLocationCoordinate2D(latitude: 47.457925,
longitude: 8.548466)
let span = MKCoordinateSpan(latitudeDelta: 0.05, longitudeDelta: 0.05)
let region = MKCoordinateRegion(center: location, span: span)
mapView.setRegion(region, animated: true)
}
}
Thank you and I hope you can help!
There are a lot of way to embed image into your maps.
Annotation Views
Callouts
Custom Map Tile
Explain your need more, and maybe we can help better to how to get there.
You are adding overlay over the map. We want to change with specific map tile.
func createLocalUrl(forImageNamed name: String) -> URL? {
let fileManager = FileManager.default
let cacheDirectory = fileManager.urls(for: .cachesDirectory, in: .userDomainMask)[0]
let url = cacheDirectory.appendingPathComponent("\(name).png")
guard fileManager.fileExists(atPath: url.path) else {
guard
let image = UIImage(named: name),
let data = image.pngData()
else { return nil }
fileManager.createFile(atPath: url.path, contents: data, attributes: nil)
return url
}
return url
}
func setupTiles() {
let url = createLocalUrl(forImageNamed: "yourImageName")
let template = url?.absoluteString
let overlay = MKTileOverlay(urlTemplate: template)
overlay.canReplaceMapContent = true
self.tileOverlay = overlay
mapView.addOverlay(overlay)
self.tileRenderer = MKTileOverlayRenderer(tileOverlay: overlay)
}
func isInDesiredArea(middlePoint: MKMapPoint) -> Bool {
//mapView has convert function which converts CGPoint ->
//CLLocationCoordinate2D and vice versa Use this function and,
//Your polygon has boundingMapRect which has contains function.
//Also your map has func mapView(_ mapView: MKMapView,
//regionDidChangeAnimated animated: Bool) which runs whenever region changes..
return myBoundsPolygon.boundingMapRect.hasContain(middlePoint)
}
func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool) {
//Convert middle point of your view to CLLocationCoordinate2D
//Convert your coordinate to MKMapPoint
if isInDesiredArea(middlePoint: point) {
setupTiles()
}
}
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
....
if overlay is MKTileOverlay {
return tileRenderer
}

mapview not centring on current users location

I'm trying to centre the mapview on the users location but so far its not working. I've tried to test it on my physical device with no luck and I can't find a solution that works please help me.
class MapViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {
var mapView: MKMapView!
var locationManager: CLLocationManager!
let distanceSpan: Double = 500
override func viewDidLoad() {
super.viewDidLoad()
setupMapView()
}
fileprivate func setupLocationManager() {self.locationManager.requestWhenInUseAuthorization()
if CLLocationManager.locationServicesEnabled() == true {
if CLLocationManager.authorizationStatus() == .restricted || CLLocationManager.authorizationStatus() == .denied || CLLocationManager.authorizationStatus() == .notDetermined {
locationManager.requestWhenInUseAuthorization()
}
locationManager.desiredAccuracy = 1.0
locationManager.delegate = self
locationManager.startUpdatingLocation()
} else {
print("PLease turn on location services or GPS")
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let region = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: locations[0].coordinate.latitude, longitude: locations[0].coordinate.longitude), span: MKCoordinateSpan(latitudeDelta: 0.002, longitudeDelta: 0.002))
self.mapView.setRegion(region, animated: true)
}
fileprivate func setupMapView() {
let mView = MKMapView(frame: CGRect(x: 0, y: 20, width: view.frame.width, height: view.frame.height))
mView.showsUserLocation = true
view.addSubview(mView)
self.mapView = mView
}
You need to update the camera on the new location.
Read here for more information.
Basically you need to implamant the function CameraUpdate().

Swift- segue between views with map annotation button

I relatively new to programming and need help switching between views by tapping a button in a mapView annotated pin.
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
//REF
#IBOutlet weak var mapView: MKMapView!
#IBOutlet weak var bottompnl: UIImageView!
#IBAction func mysticsbtn(sender: AnyObject) {
}
#IBAction func bondibtn(sender: AnyObject) {
}
//MAP
let locationManager = CLLocationManager()
//Annotation
func mapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! {
let identifier = "beach"
if annotation is Beach {
var annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier(identifier)
if annotationView == nil {
annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
annotationView!.canShowCallout = true
let btn = UIButton(type: .DetailDisclosure)
annotationView!.rightCalloutAccessoryView = btn
} else {
annotationView!.annotation = annotation
}
return annotationView
self.performSegueWithIdentifier("mysticssegue", sender: nil)
}
return nil
}
override func viewDidLoad() {
super.viewDidLoad()
let annotations = getMapAnnotations()
// Add mappoints to Map
mapView.addAnnotations(annotations)
mapView.delegate = self
//MAP
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
//MAKES THE DOT
self.mapView.showsUserLocation = true
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MAP: Location Delegates Methods
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations.last
let centre = CLLocationCoordinate2D(latitude: location!.coordinate.latitude, longitude: location!.coordinate.longitude)
let region = MKCoordinateRegion(center: centre, span: MKCoordinateSpan(latitudeDelta: 3, longitudeDelta: 3))
self.mapView.setRegion(region, animated: true)
self.locationManager.startUpdatingLocation()
}
//TO FIND ERROS
func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
print("Erros: " + error.localizedDescription)
}
//MARK:- Annotations
func getMapAnnotations() -> [Beach] {
var annotations:Array = [Beach]()
//load plist file
var beaches: NSArray?
if let path = NSBundle.mainBundle().pathForResource("beaches", ofType: "plist") {
beaches = NSArray(contentsOfFile: path)
}
if let items = beaches {
for item in items {
let lat = item.valueForKey("lat") as! Double
let long = item.valueForKey("long")as! Double
let annotation = Beach(latitude: lat, longitude: long)
annotation.title = item.valueForKey("title") as? String
annotations.append(annotation)
}
}
return annotations
}
//END
}
It looks like you're returning from the function mapView before calling performSegueWithIdentifier.
return annotationView
self.performSegueWithIdentifier("mysticssegue", sender: nil)
Try reversing the order of these two lines. I also noticed that you have some #IBAction methods that have no code in them.

Pressing Button Centers\Focuses MKmapView onto User's location, Swift

My code:
Please anyone ! How to make this button work !?!??!
What do i put in the #IBAction brackets to have the function i want ?
import UIKit
import MapKit
import CoreLocation
class MapViewController: UIViewController,MKMapViewDelegate, CLLocationManagerDelegate{
#IBOutlet weak var mapView: MKMapView!
let locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
//==========RegionLocation : =========
// Init the zoom level
let coordinate:CLLocationCoordinate2D = CLLocationCoordinate2D(latitude: 31.30, longitude: 34.45)
let span = MKCoordinateSpanMake(125, 125)
let region = MKCoordinateRegionMake(coordinate, span)
self.mapView.setRegion(region, animated: true)
//====================================\\
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
//Dispose of resources that can be re created.
}
//Mark : Location
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.06, longitudeDelta: 0.06))
self.mapView.setRegion(region, animated: true)
self.locationManager.stopUpdatingLocation()
}
func locationManager(manager: CLLocationManager, didFailWithError error: NSError)
{
print("Errors: " + error.localizedDescription)
}
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
if annotation is MKUserLocation {
return nil
}
let reuseID = "pin"
var pinView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseID) as? MKPinAnnotationView
if(pinView == nil) {
pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseID)
pinView!.canShowCallout = true
pinView!.animatesDrop = true
pinView!.rightCalloutAccessoryView = UIButton(type: UIButtonType.DetailDisclosure) as UIButton
let smallSquare = CGSize(width: 30, height: 30)
let button = UIButton(frame: CGRect(origin: CGPointZero, size: smallSquare))
button.setBackgroundImage(UIImage(named: "Car"), forState: .Normal)
pinView?.leftCalloutAccessoryView = button
}
else
{
pinView!.annotation = annotation
}
return pinView
}
but when i put in the button action segment nothing happens when i press on it ?
Anyone can Guide me on How do i center the mapView onto the user location Blue dot ?
Try this
#IBAction func centerLocationButton(sender: UIButton) {
mapView.setCenterCoordinate(mapView.userLocation.coordinate, animated: true)
}
In order to use MKMapView in correct way just follow the following below code.
// `viewDidLoad` method
#IBOutlet weak var map: MKMapView!
var locationManager: CLLocationManager!
override func viewDidLoad() {
super.viewDidLoad()
// code for enable location seivices
if (CLLocationManager.locationServicesEnabled())
{
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
}
}
override CLLocationManager.didUpdateLocations see below (part of CLLocationManagerDelegate) to get notified when the location manager retrieves the current location.
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
let location = locations.last as CLLocation
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)
}
have a note: If your target is iOS 8, you must include the NSLocationAlwaysUsageDescription key in your Info.plist to get the location services to work.
if you want to set region in a custom way using button action just save lat and long and pass like:
#IBAction func setMap(sender: UIButton) {
let center = CLLocationCoordinate2D(latitude: lat, longitude: long)
let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01))
self.map.setRegion(region, animated: true)
}
here is Google map guidelines. and useful tutorial
I can see what you need is to have a button to center the mapView to your current location. It is exactly same as vaibhab's answer with little modifications.
Just create to button and link the action to the viewcontroller class then copy the same code in the IBAction of the button.
#IBAction func updateCurrentLocation(_ sender: AnyObject) {
if CLLocationManager.locationServicesEnabled() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
} else {
// Alert to enable location services on iphone first
}
}
Plus you can just add a small line of code to show the blue indicator of the location of the user. In the func locationManager.
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [AnyObject]) {
self.mapView.showsUserLocation = true
}
Make sure when you are using the simulator just add a custom location from the simulators menu. Debug ---> location ----> Custom
If using a real mobile just make sure that the location services is on in the Settings---> General----> Privacy