I've been doing a project in Swift 3.
I choose my points by touching in the map and after that I link them with a line.
I've been trying to fill the area between those points with the color Red but without any success. How can I acomplish this?
I set the fill color, in the mapview, but it isn't working.
I have this code so far:
import UIKit
import MapKit
class ViewController: UIViewController, MKMapViewDelegate {
#IBOutlet var map: MKMapView!
var points: [CLLocationCoordinate2D] = [CLLocationCoordinate2D]() //all touched points
override func viewDidLoad() {
super.viewDidLoad()
map.delegate = self
let latitude: CLLocationDegrees = 38.925560
let longitude: CLLocationDegrees = -9.229723
let lanDelta: CLLocationDegrees = 0.05
let lonDelta: CLLocationDegrees = 0.05
let span = MKCoordinateSpan(latitudeDelta: lanDelta, longitudeDelta: lonDelta)
let coordinates = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
let region = MKCoordinateRegion(center: coordinates, span: span)
map.setRegion(region, animated: true)
let uilpgr = UILongPressGestureRecognizer(target: self, action: #selector(ViewController.longpress(gestureRecognizer:)))
uilpgr.minimumPressDuration = 0.5
map.addGestureRecognizer(uilpgr)
}
func longpress(gestureRecognizer: UIGestureRecognizer) {
guard gestureRecognizer.state == .began else { return }
let touchPoint = gestureRecognizer.location(in: self.map)
let coordinate = map.convert(touchPoint, toCoordinateFrom: self.map)
let annotation = MKPointAnnotation()
annotation.coordinate = coordinate
annotation.title = "My Place"
map.addAnnotation(annotation)
// print("longpress activated")
points.append(annotation.coordinate)
let polyline = MKPolyline(coordinates: points, count: points.count)
map.add(polyline)
}
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
let polylineRenderer = MKPolylineRenderer(overlay: overlay)
polylineRenderer.strokeColor = UIColor.blue
polylineRenderer.fillColor = UIColor.red
polylineRenderer.lineWidth = 5
return polylineRenderer
}
}
MKPolyLine will render a line. If you want a filled polygon you need MKPolyon. If you want both an outline and a fill, use both.
fileprivate var polygon: MKPolygon? = nil
func addPolygon() {
let polygon = MKPolygon(coordinates: &polygonCoordinates, count: polygonCoordinates.count)
self.polygon = polygon
mapView.add(polygon)
}
func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
if let _ = overlay as? MKPolyline {
let renderer = MKPolylineRenderer(polyline: polyLine!)
renderer.strokeColor = UIColor.blue
renderer.lineWidth = 2
return renderer
} else {
let renderer = MKPolygonRenderer(polygon: polygon)
renderer.fillColor = UIColor.blue.withAlphaComponent(0.25)
return renderer
}
}
Related
The application I developed creates an annotation on the map when pressed and held. When this annotation is touched, the button and other information appear. But I want the button and other information to appear directly (without touching it). And I don't know that how to use the button.
import UIKit
import MapKit
import CoreLocation
class choosingVC: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate{
var locationManager = CLLocationManager()
#IBOutlet weak var mapView: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
mapView.delegate = self
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
let gestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(ChooseLocation(gestureRecognizer:)))
gestureRecognizer.minimumPressDuration = 2
mapView.addGestureRecognizer(gestureRecognizer)
}
#objc func ChooseLocation(gestureRecognizer:UILongPressGestureRecognizer){
if gestureRecognizer.state == .began {
let touchPoint = gestureRecognizer.location(in: mapView)
let touchCoordinate = mapView.convert(touchPoint, toCoordinateFrom: mapView)
let annotation = MKPointAnnotation()
annotation.coordinate = touchCoordinate
annotation.title = "seçitiğiniz bölge"
annotation.subtitle = "örnek"
mapView.addAnnotation(annotation)
}
}
//annotation artı butonu ekledik.
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
if !(annotation is MKUserLocation) {
let pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: String(annotation.hash))
let rightButton = UIButton(type: .contactAdd)
rightButton.tag = annotation.hash
pinView.animatesDrop = true
pinView.canShowCallout = true
pinView.rightCalloutAccessoryView = rightButton
return pinView
}
else {
return nil
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = CLLocationCoordinate2D(latitude: locations[0].coordinate.latitude, longitude: locations[0].coordinate.longitude)
let span = MKCoordinateSpan(latitudeDelta: 0.1, longitudeDelta: 0.1)
let region = MKCoordinateRegion(center: location, span: span)
mapView.setRegion(region, animated: true)
}
}
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)
}
}
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()
}
}
----------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
}
I can't seem to get the final part of Ray Wenderlich's mapkit tutorial to work. I get the pins to display correctly but when I click on the pin, it doesn't open in Maps as I would like it too. Here is the link to the full tutorial (Link)
And here is my code:
import Foundation
import UIKit
import MapKit
import AddressBook
class CroquisMapView: UIViewController, MKMapViewDelegate {
var section : Int?
var index : Int?
#IBOutlet weak var mapView: MKMapView!
let regionRadius: CLLocationDistance = 1000
func centerMapOnLocation(location: CLLocation) {
let coordinateRegion = MKCoordinateRegionMakeWithDistance(location.coordinate,
regionRadius * 2.0, regionRadius * 2.0)
mapView.setRegion(coordinateRegion, animated: true)
}
override func viewDidLoad() {
mapView.delegate = self
let coordenadas = croquisGruposArray[section!].items[index!].coordenadas
let coordenadasArray = coordenadas!.characters.split{$0 == ","}.map(String.init)
guard let lat = NSNumberFormatter().numberFromString(coordenadasArray[0])?.doubleValue,
let long = NSNumberFormatter().numberFromString(coordenadasArray[1])?.doubleValue else {
return
}
let initialLocation = CLLocation(latitude: lat, longitude: long)
let artwork = Artwork(title: "\(croquisGruposArray[section!].items[index!].descripcion!)",
locationName: "\(globalLigaNombre!)",
discipline: "Futbol",
coordinate: CLLocationCoordinate2D(latitude: lat, longitude: long))
mapView.addAnnotation(artwork)
centerMapOnLocation(initialLocation)
}
}
class Artwork: NSObject, MKAnnotation {
let title: String?
let locationName: String
let discipline: String
let coordinate: CLLocationCoordinate2D
init(title: String, locationName: String, discipline: String, coordinate: CLLocationCoordinate2D) {
self.title = title
self.locationName = locationName
self.discipline = discipline
self.coordinate = coordinate
super.init()
}
var subtitle: String? {
return locationName
}
func mapItem() -> MKMapItem {
let addressDictionary = [String(kABPersonAddressStreetKey): locationName]
let placemark = MKPlacemark(coordinate: coordinate, addressDictionary: addressDictionary)
let mapItem = MKMapItem(placemark: placemark)
mapItem.name = title
return mapItem
}
func mapView(mapView: MKMapView!, annotationView view: MKAnnotationView!, calloutAccessoryControlTapped control: UIControl!) {
print("CLICKED")
let location = view.annotation as! Artwork
let launchOptions = [MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving]
location.mapItem().openInMapsWithLaunchOptions(launchOptions)
}
}
extension CroquisMapView {
// 1
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
if let annotation = annotation as? Artwork {
let identifier = "pin"
var view: MKPinAnnotationView
if let dequeuedView = mapView.dequeueReusableAnnotationViewWithIdentifier(identifier)
as? MKPinAnnotationView { // 2
dequeuedView.annotation = annotation
view = dequeuedView
} else {
// 3
view = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
view.canShowCallout = true
view.calloutOffset = CGPoint(x: -5, y: 5)
view.rightCalloutAccessoryView = UIButton(type: .DetailDisclosure) as UIView
}
return view
}
return nil
}
}
Figured it out: I wasn't calling calloutAccessoryControlTapped in my main class. I added it and it with the code provided by Andrej:
func mapView(mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
let url = NSURL(string: "http://maps.apple.com/?q=\(lat),\(long)")
if UIApplication.sharedApplication().canOpenURL(url!) == true {
UIApplication.sharedApplication().openURL(url!)
}
}
You can try this:
let url = NSURL(string: "http://maps.apple.com/?q=44.33833,13.98131")
if UIApplication.sharedApplication().canOpenURL(url!) == true
{
UIApplication.sharedApplication().openURL(url!)
}
You can also do like this:
extension ViewController : MKMapViewDelegate {
func getDirections(){ // Here you can put everything, this function is calling when the user select the dialogue pin's bubble. I propose a code who open the application Map.
guard let selectedPin = selectedPin else { return }
let mapItem = MKMapItem(placemark: selectedPin)
let launchOptions = [MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving]
mapItem.openInMapsWithLaunchOptions(launchOptions)
}
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView?{
guard !(annotation is MKUserLocation) else { return nil }
if annotation is MKUserLocation {
//return nil so map view draws "blue dot" for standard user location
return nil
}
let reuseId = "pin"
var pinView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId) as? MKPinAnnotationView
if pinView == nil {
pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
}
pinView?.pinTintColor = UIColor.orangeColor()
pinView?.canShowCallout = true
let smallSquare = CGSize(width: 30, height: 30)
let button = UIButton(frame: CGRect(origin: CGPointZero, size: smallSquare))
button.setBackgroundImage(UIImage(named: "car"), forState: .Normal)
button.addTarget(self, action: #selector(self.getDirections), forControlEvents: .TouchUpInside)
pinView?.leftCalloutAccessoryView = button
return pinView}
}