Swift 3 Current Location to Simple location between MKPolyline - swift

Hello i have working codes for current location blue dot show and simple location pin show I want to do line between them with MKPolyline my clear codes under below.
import UIKit
import CoreLocation
import MapKit
class ShowMapViewController: UIViewController,MKMapViewDelegate ,CLLocationManagerDelegate {
#IBOutlet weak var mapView: MKMapView!
var showmapListcomming = String()
let locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
locationManager.requestLocation()
locationManager.requestWhenInUseAuthorization()
locationManager.requestAlwaysAuthorization()
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation()
mapView.showsUserLocation = true
// Show Map
var myStringArrctakes = showmapListcomming.components(separatedBy: ",")
let annotation = MKPointAnnotation()
let latitude:CLLocationDegrees = (myStringArrctakes[6] as NSString).doubleValue
let longitude:CLLocationDegrees = (myStringArrctakes[5] as NSString).doubleValue
let latDelta:CLLocationDegrees = 30
let lonDelta:CLLocationDegrees = 30
let span:MKCoordinateSpan = MKCoordinateSpanMake(latDelta, lonDelta)
let locations:CLLocationCoordinate2D = CLLocationCoordinate2DMake(latitude, longitude)
let region:MKCoordinateRegion = MKCoordinateRegionMake(locations, span)
mapView.setRegion(region, animated: false)
annotation.coordinate = locations
annotation.title = myStringArrctakes[1]
annotation.subtitle = "\(myStringArrctakes[2])"
mapView.addAnnotation(annotation)
}
// MARK: - MKMapViewDelegate methods
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
let annotationView = MKPinAnnotationView()
return annotationView
}
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.mapView.setRegion(region, animated: true)
if let location = locations.last {
print("Found User's location: \(location)")
print("Latitude: \(location.coordinate.latitude) Longitude: \(location.coordinate.longitude)")
}
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: NSError) {
print("Failed to find user's location: \(error.localizedDescription)")
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
I think easy but I didn't resolve it. Im waiting your ideas , I think will be help many people so in swift 3 I didn't find anything like this on web.
Thanks

Related

How to replicate Snapchat Map in swift?

Lately I have been working on a little project. I would like to replicate the snapchat map program in swift. Basically I would like to display on a map a pin that indicates the position of my device in which it is installed the program. I have written some code in swift but I am not so happy with it. Any advice would be more than appreciated.
import Foundation
import CoreLocation
import MapKit
class DiscoverViewController : UIViewController, CLLocationManagerDelegate {
#IBOutlet weak var map: MKMapView!
let locationManager: CLLocationManager! = nil
override func viewDidLoad()
{
super.viewDidLoad()
//for use in background
self.locationManager.requestAlwaysAuthorization()
//for use in foreground
self.locationManager.requestWhenInUseAuthorization()
if (CLLocationManager.locationServicesEnabled())
{
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
}
}
func locationManager(manager: CLLocationManager!, didUpdateLocations locations:
[AnyObject]!) { var locValue:CLLocationCoordinate2D = manager.location.coordinate
println("locations = \(localValue.latitude) \(localValue.longitude)")
let center = CLLocationCoordinate2D(latitude: locValue.latitude, longitude:
locValue.longitude)
let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta:
0.01, longitudeDelta: 0.01))
self.map.setRegion(region, animated: true)
var currentLocation = CLLocation()
var locationLat = currentLocation.coordinate.latitude
var locationLong = currentLocation.coordinate.longitude
println("locations = \(locationLat) \(locationLong) \
(currentLocation.coordinate.latitude) \(currentLocation.coordinate.longitude)")
}
func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {
println("Errore while updating location" + error.localizedDescription)
}
func locationManagerDidPauseLocationUpdates(_ manager: CLLocationManager) {
<#code#>
}
}

Add a pin on map at user's location

I want add a pin near a user's location.
i can do it with static coordinate
but i can't do it with user's location. I need a button that adds it
i made the button but when i press it it doesn’t do anything
and i can't repress the same button
this is what i tried
import UIKit
import MapKit
import CoreLocation
import LocalAuthentication
class ViewController: UIViewController {
// Per la mappa
#IBOutlet weak var Map: MKMapView!
let newPin = MKPointAnnotation()
let locationManager:CLLocationManager = CLLocationManager()
// FOTOCAMERA
//
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
locationManager.requestWhenInUseAuthorization()
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.distanceFilter = kCLDistanceFilterNone
locationManager.startUpdatingLocation()
Map.showsUserLocation = true
}
#IBAction func Add(_ sender: Any) {
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
let span : MKCoordinateSpan = MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01)
var userLocation : CLLocation = locations[0] as! CLLocation
let location : CLLocationCoordinate2D = CLLocationCoordinate2DMake(userLocation.coordinate.latitude, userLocation.coordinate.longitude)
let region : MKCoordinateRegion = MKCoordinateRegion(center: location, span: span)
Map.setRegion(region, animated: true)
let annotation = MKPointAnnotation()
annotation.coordinate = CLLocationCoordinate2DMake ( userLocation.coordinate.latitude,userLocation.coordinate.longitude)
annotation.title = "urgenza"
annotation.subtitle = "QUI SI TROVA LA TUA URGENZA"
Map.addAnnotation(annotation)
}
}

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
}

Swift MKMapView Drop a Pin Annotation to Current Location

I am looking to be able to ask the app user for his/her current location and a pin to be automatically dropped on that location. Here is my code for grabbing the current location, but I am having trouble understanding how I can drop a pin for the current location.
import UIKit
import MapKit
import CoreLocation
class MapVC: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
#IBOutlet weak var map: MKMapView!
let locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
// User's location
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
if #available(iOS 8.0, *) {
locationManager.requestAlwaysAuthorization()
} else {
// Fallback on earlier versions
}
locationManager.startUpdatingLocation()
// add gesture recognizer
let longPress = UILongPressGestureRecognizer(target: self, action: #selector(MapVC.mapLongPress(_:))) // colon needs to pass through info
longPress.minimumPressDuration = 1.5 // in seconds
//add gesture recognition
map.addGestureRecognizer(longPress)
}
// func called when gesture recognizer detects a long press
func mapLongPress(_ recognizer: UIGestureRecognizer) {
print("A long press has been detected.")
let touchedAt = recognizer.location(in: self.map) // adds the location on the view it was pressed
let touchedAtCoordinate : CLLocationCoordinate2D = map.convert(touchedAt, toCoordinateFrom: self.map) // will get coordinates
let newPin = MKPointAnnotation()
newPin.coordinate = touchedAtCoordinate
map.addAnnotation(newPin)
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
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))
//set region on the map
self.map.setRegion(region, animated: true)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
If you want to add pin to user location you can do that in didUpdateLocations delegate method like this
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
mapView.removeAnnotation(newPin)
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))
//set region on the map
map.setRegion(region, animated: true)
newPin.coordinate = location.coordinate
map.addAnnotation(newPin)
}
Create a global variable for your pin
let newPin = MKPointAnnotation()
So whenever user will move to a new location the previous pin will be removed and a new pin will be added to updated location.
First you need to add annotation in didUpdateLocations method and then whenever any annotation is added then viewForAnnotation is called so here is the code and corresponding method to add pin in user current location :
//Adding Annotation on Current Location
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
//Get Current Location
let location = locations.last! as CLLocation
let userLocation:CLLocation = locations[0] as CLLocation
let myAnnotation: MKPointAnnotation = MKPointAnnotation()
myAnnotation.coordinate = CLLocationCoordinate2DMake(userLocation.coordinate.latitude, userLocation.coordinate.longitude)
myAnnotation.title = "Current location"
map.addAnnotation(myAnnotation)
}
//Adding image to user current location pin
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
guard !(annotation is MKUserLocation) else {
let annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: "userLocation")
annotationView.image = UIImage(named:"anyimage.png")
return annotationView
}
return nil
}
Feel free to ask if any further issue.

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