Annotations won't appear on MapView - ios

I'm having trouble getting my annotations to display on my map view. Nothing is displaying right now. What is wrong with my code ?
Here is my base map view controller:
import UIKit
import MapKit
import CoreLocation
class MapViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {
let goldenWordsYellow = UIColor(red: 247.00/255.0, green: 192.00/255.0, blue: 51.00/255.0, alpha: 0.5)
// Map View outlet declaration
#IBOutlet weak var mapView: MKMapView!
// Hamburger button declaration
#IBOutlet weak var menuButton:UIBarButtonItem!
var locationManager: CLLocationManager?
/* Really ugly code where I declare all of my static data */
let coordinatesARC = IssueLocation(locationName: "ARC", coordinate: CLLocationCoordinate2D(latitude: -76.49416565895079, longitude: 44.22928743712073))
let coordinatesJDUC = IssueLocation(locationName: "JDUC", coordinate: CLLocationCoordinate2D(latitude: -76.49507761001587, longitude: 44.22838027067406))
let coordinatesStaufferLibrary = IssueLocation(locationName: "Stauffer Library", coordinate: CLLocationCoordinate2D(latitude: -76.49615049362183, longitude: 44.228418710213944))
let coordinatesWalterLightHall = IssueLocation(locationName: "Walter Light Hall", coordinate: CLLocationCoordinate2D(latitude: -76.49166584014893, longitude: 44.22794205814507))
let coordinatesDupuisHall = IssueLocation(locationName: "Dupuis Hall", coordinate: CLLocationCoordinate2D(latitude: -76.4927065372467, longitude: 44.22867241054762))
let coordinatesHumphreyHall = IssueLocation(locationName: "Humphrey Hall", coordinate: CLLocationCoordinate2D(latitude: -76.49212718009949, longitude: 44.22688879714365))
let coordinatesBiosciencesComplex = IssueLocation(locationName: "Biosciences Complex", coordinate: CLLocationCoordinate2D(latitude: -76.49117231369019, longitude: 44.226327562781904))
let coordinatesBMH = IssueLocation(locationName: "Beamish-Munro Hall", coordinate: CLLocationCoordinate2D(latitude: -76.49271726608276, longitude: 44.228195760533175))
let coordinatesBotterellHall = IssueLocation(locationName: "Botterell Hall", coordinate: CLLocationCoordinate2D(latitude: -76.49160146713257, longitude: 44.22447468258034))
let coordinatesEtheringtonHall = IssueLocation(locationName: "Etherington Hall", coordinate: CLLocationCoordinate2D(latitude: -76.49390816688538, longitude: 44.224282471751785))
let coordinatesJefferyHall = IssueLocation(locationName: "Jeffery Hall", coordinate: CLLocationCoordinate2D(latitude: -76.49605393409729, longitude: 44.22590855555731))
let coordinatesEllisHall = IssueLocation(locationName: "Ellis Hall", coordinate: CLLocationCoordinate2D(latitude: -76.49602174758911, longitude: 44.22636984774898))
let coordinatesMackintoshCorryHall = IssueLocation(locationName: "Mackintosh-Corry Hall", coordinate: CLLocationCoordinate2D(latitude: -76.49697124958038, longitude: 44.22677731951135))
let coordinatesChernoffHall = IssueLocation(locationName: "Chernoff Hall", coordinate: CLLocationCoordinate2D(latitude: -76.49884343147278, longitude: 44.22436704459368))
let coordinatesLeggetHall = IssueLocation(locationName: "Legget Hall", coordinate: CLLocationCoordinate2D(latitude: -76.49749159812927, longitude: 44.22362126170883))
let coordinatesLeonardHall = IssueLocation(locationName: "Leonard Hall", coordinate: CLLocationCoordinate2D(latitude: -76.50065660476685, longitude: 44.22429016019697))
let coordinatesVictoriaHall = IssueLocation(locationName: "Victoria Hall", coordinate: CLLocationCoordinate2D(latitude: -76.49863958358765, longitude: 44.22550492192426))
let coordinatesStirlingHall = IssueLocation(locationName: "Stirling Hall", coordinate: CLLocationCoordinate2D(latitude: -76.49767398834229, longitude: 44.22463613919133))
let coordinatesWestCampus = IssueLocation(locationName: "West Campus", coordinate: CLLocationCoordinate2D(latitude: -76.51471138000487, longitude: 44.22438242146097))
override func viewDidLoad() {
super.viewDidLoad()
// Hamburger button configuration
if self.revealViewController() != nil {
menuButton.target = self.revealViewController()
menuButton.action = "revealToggle:"
self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
}
// Setting the Map type to standard
mapView.mapType = MKMapType.Standard
// Configuring locationManager and mapView delegate
locationManager = CLLocationManager()
mapView.delegate = self
// Set the center of campus as the first location, before we show the actual user location
let initialLocation = CLLocationCoordinate2D(latitude: 44.226181, longitude: -76.495614)
let latitudeDelta:CLLocationDegrees = 0.015
let longitudeDelta:CLLocationDegrees = 0.015
let span = MKCoordinateSpanMake(latitudeDelta, longitudeDelta)
let coordinateRegion = MKCoordinateRegionMake(initialLocation, span)
mapView.setRegion(coordinateRegion, animated: true)
let ARCAnnotation = MKPointAnnotation()
ARCAnnotation.title = coordinatesARC.locationName
ARCAnnotation.subtitle = coordinatesARC.locationName
ARCAnnotation.coordinate = coordinatesARC.coordinate
mapView.addAnnotation(ARCAnnotation)
// Adding all annotations to the map view
mapView.addAnnotation(coordinatesARC)
mapView.addAnnotation(coordinatesJDUC)
mapView.addAnnotation(coordinatesStaufferLibrary)
mapView.addAnnotation(coordinatesWalterLightHall)
mapView.addAnnotation(coordinatesDupuisHall)
mapView.addAnnotation(coordinatesHumphreyHall)
mapView.addAnnotation(coordinatesBiosciencesComplex)
mapView.addAnnotation(coordinatesBMH)
mapView.addAnnotation(coordinatesBotterellHall)
mapView.addAnnotation(coordinatesEtheringtonHall)
mapView.addAnnotation(coordinatesJefferyHall)
mapView.addAnnotation(coordinatesEllisHall)
mapView.addAnnotation(coordinatesMackintoshCorryHall)
mapView.addAnnotation(coordinatesChernoffHall)
mapView.addAnnotation(coordinatesLeggetHall)
mapView.addAnnotation(coordinatesLeonardHall)
mapView.addAnnotation(coordinatesVictoriaHall)
mapView.addAnnotation(coordinatesStirlingHall)
mapView.addAnnotation(coordinatesWestCampus)
mapView.showsUserLocation = true
locationManager?.startUpdatingLocation()
}
func mapView(mapView: MKMapView, didUpdateUserLocation userLocation: MKUserLocation) {
mapView.centerCoordinate = CLLocationCoordinate2D(latitude: 44.226181, longitude: -76.495614)
}
func checkLocationAuthorizationStatus() {
if CLLocationManager.authorizationStatus() == .AuthorizedWhenInUse {
mapView.showsUserLocation = true
} else {
locationManager?.requestWhenInUseAuthorization()
}
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
checkLocationAuthorizationStatus()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
Here is my map view controller extension:
import Foundation
import MapKit
extension MapViewController {
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
if let annotation = annotation as? IssueLocation {
let identifier = "pin"
var view: MKPinAnnotationView
if let dequeuedView = mapView.dequeueReusableAnnotationViewWithIdentifier(identifier) as? MKPinAnnotationView {
dequeuedView.annotation = annotation // NOTE: 2 options here for the "annotation" at the end of this line. I choose the first one but am in doubt.
view = dequeuedView
} else {
view = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier) // NOTE: another unsure choice for the "annotation" right before the comma
view.canShowCallout = true
view.calloutOffset = CGPoint(x: -5, y: 5)
view.rightCalloutAccessoryView = UIButton(type: UIButtonType.DetailDisclosure) as UIView
}
return view
}
return nil
}
func mapView(mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
let location = view.annotation as! IssueLocation
let launchOptions = [MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeWalking]
location.mapItem().openInMapsWithLaunchOptions(launchOptions)
}
}
And here is my class:
import Foundation
import MapKit
import AddressBook
import Contacts
class IssueLocation: NSObject, MKAnnotation {
let locationName: String
let coordinate: CLLocationCoordinate2D
init(locationName: String, coordinate: CLLocationCoordinate2D) {
self.locationName = locationName
self.coordinate = coordinate
super.init()
}
var subtitle: String? {
return locationName
}
var title: String? {
return locationName
}
func mapItem() -> MKMapItem {
let addressDictionary = [String(CNPostalAddressStreetKey): locationName]
let placemark = MKPlacemark(coordinate: coordinate, addressDictionary: addressDictionary)
let mapItem = MKMapItem(placemark: placemark)
mapItem.name = locationName
return mapItem

This issue is with your coordinates.
Your code:
let coordinatesARC = IssueLocation(locationName: "ARC", coordinate: CLLocationCoordinate2D(latitude: -76.49416565895079, longitude: 44.22928743712073))
let coordinatesJDUC = IssueLocation(locationName: "JDUC", coordinate: CLLocationCoordinate2D(latitude: -76.49507761001587, longitude: 44.22838027067406))
Corrected code:
let coordinatesARC = IssueLocation(locationName: "ARC", coordinate: CLLocationCoordinate2D(latitude: 44.22928743712073, longitude: -76.49416565895079))
let coordinatesJDUC = IssueLocation(locationName: "JDUC", coordinate: CLLocationCoordinate2D(latitude: 44.22838027067406, longitude: -76.49507761001587))

Related

Set MapKit pins with different colors

I am new in iOS and I implemented a MapKit with static markers from different arrays types and they are working fine , I am trying to put pins that come from shops array to be blue for example , and pins that come from community read , etc .. I have no idea about how to do this
at all , they are all in red in the map and my goal is to change the color for every array of pins
here what I have tried :
import UIKit
import MapKit
class myMapViewController: UIViewController, MKMapViewDelegate {
var shops = [Shops]()
var communities = [Community]()
var cyclists = [Cyclist]()
var circuits = [Circuit]()
#IBOutlet weak var myMap: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
shops.append(Shops(id: 0, title: "Shop1", latitude: 36.553015 , longitude: 10.592774))
shops.append(Shops(id: 0, title: "Shop2", latitude: 35.499414 , longitude: 10.824846))
communities.append(Community(id: 0, title: "community1", latitude: 37.276943 , longitude: 10.934709 ))
communities.append(Community(id: 0, title: "community2", latitude: 35.427828 , longitude: 9.748186 ))
circuits.append(Circuit(id: 0, title: "circuit1", latitude: 33.773035 , longitude: 10.857805 ))
cyclists.append(Cyclist(id: 0, title: "cyclist1", latitude: 35.785118 , longitude: 10.000871 ))
createShopsAnnotations(locations: shops)
createCircuitsAnnotations(locations: circuits)
createCommunityAnnotations(locations: communities)
createCyclistsAnnotations(locations: cyclists)
}
func createShopsAnnotations(locations:[Shops]){
for location in locations {
let annotations = MKPointAnnotation()
annotations.title = location.title as? String
annotations.coordinate = CLLocationCoordinate2D(latitude: location.latitude as! CLLocationDegrees , longitude: location.longitude as! CLLocationDegrees)
myMap.addAnnotation(annotations)
}
}
func createCircuitsAnnotations(locations:[Circuit]){
for location in locations {
let annotations = MKPointAnnotation()
annotations.title = location.title as? String
annotations.coordinate = CLLocationCoordinate2D(latitude: location.latitude as! CLLocationDegrees , longitude: location.longitude as! CLLocationDegrees)
myMap.addAnnotation(annotations)
}
}
func createCommunityAnnotations(locations:[Community]){
for location in locations {
let annotations = MKPointAnnotation()
annotations.title = location.title as? String
annotations.coordinate = CLLocationCoordinate2D(latitude: location.latitude as! CLLocationDegrees , longitude: location.longitude as! CLLocationDegrees)
myMap.addAnnotation(annotations)
}
}
func createCyclistsAnnotations(locations:[Cyclist]){
for location in locations {
let annotations = MKPointAnnotation()
annotations.title = location.title as? String
annotations.coordinate = CLLocationCoordinate2D(latitude: location.latitude as! CLLocationDegrees , longitude: location.longitude as! CLLocationDegrees)
myMap.addAnnotation(annotations)
}
}
}
I have headed some tutorials but I was not able to apply them on my example.
The basic idea is to make an annotation view type to render the correct color. So, assume for a second that you have four annotation types (see below), then you might have an annotation view type like so:
class AnnotationView: MKMarkerAnnotationView {
override var annotation: MKAnnotation? { didSet { update(for: annotation) } }
override init(annotation: MKAnnotation?, reuseIdentifier: String?) {
super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
update(for: annotation)
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
func update(for annotation: MKAnnotation?) {
switch annotation {
case is Shop: markerTintColor = .blue
case is Community: markerTintColor = .cyan
case is Cyclist: markerTintColor = .green
case is Circuit: markerTintColor = .red
default: break
}
}
}
And then you would have your view controller register that annotation view for your map view:
override func viewDidLoad() {
super.viewDidLoad()
mapView.register(AnnotationView.self, forAnnotationViewWithReuseIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier)
...
}
Note, when you register an annotation view type like this, you do not want to implement any mapView(_:viewFor:) method. Since iOS 11, that delegate method is not needed/recommended any more.
Anyway, that annotation view type assumes you have four types of annotations. I'd personally make Shop, Community, Cyclist and Circuit just be annotation types, e.g.
class Shop: NSObject, MKAnnotation {
let id: Int
dynamic var title: String?
dynamic var subtitle: String?
dynamic var coordinate: CLLocationCoordinate2D
init(id: Int, title: String, subtitle: String? = nil, coordinate: CLLocationCoordinate2D) {
self.id = id
self.title = title
self.subtitle = subtitle
self.coordinate = coordinate
super.init()
}
}
// repeat for the other three types
And then, when I want to add them to my map:
shops.append(Shop(id: 0, title: "Shop1", coordinate: CLLocationCoordinate2D(latitude: 36.553015, longitude: 10.592774)))
shops.append(Shop(id: 0, title: "Shop2", coordinate: CLLocationCoordinate2D(latitude: 35.499414 , longitude: 10.824846)))
communities.append(Community(id: 0, title: "community1", coordinate: CLLocationCoordinate2D(latitude: 37.276943 , longitude: 10.934709)))
communities.append(Community(id: 0, title: "community2", coordinate: CLLocationCoordinate2D(latitude: 35.427828 , longitude: 9.748186)))
circuits.append(Circuit(id: 0, title: "circuit1", coordinate: CLLocationCoordinate2D(latitude: 33.773035 , longitude: 10.857805)))
cyclists.append(Cyclist(id: 0, title: "cyclist1", coordinate: CLLocationCoordinate2D(latitude: 35.785118 , longitude: 10.000871)))
mapView.addAnnotations(shops + communities + circuits + cyclists)
Alternatively, you might have one annotation type:
enum PlaceType {
case shop, community, cyclist, circuit
}
class Place: NSObject, MKAnnotation {
let id: Int
let type: PlaceType
dynamic var title: String?
dynamic var subtitle: String?
dynamic var coordinate: CLLocationCoordinate2D
init(id: Int, type: PlaceType, title: String, subtitle: String? = nil, coordinate: CLLocationCoordinate2D) {
self.id = id
self.type = type
self.title = title
self.subtitle = subtitle
self.coordinate = coordinate
super.init()
}
}
You'd then instantiate these places:
var places = [Place]()
override func viewDidLoad() {
super.viewDidLoad()
mapView.register(AnnotationView.self, forAnnotationViewWithReuseIdentifier: MKMapViewDefaultAnnotationViewReuseIdentifier)
places = [
Place(id: 0, type: .shop, title: "Shop1", coordinate: CLLocationCoordinate2D(latitude: 36.553015, longitude: 10.592774)),
Place(id: 0, type: .shop, title: "Shop2", coordinate: CLLocationCoordinate2D(latitude: 35.499414 , longitude: 10.824846)),
Place(id: 0, type: .community, title: "community1", coordinate: CLLocationCoordinate2D(latitude: 37.276943 , longitude: 10.934709)),
Place(id: 0, type: .community, title: "community2", coordinate: CLLocationCoordinate2D(latitude: 35.427828 , longitude: 9.748186)),
Place(id: 0, type: .circuit, title: "circuit1", coordinate: CLLocationCoordinate2D(latitude: 33.773035 , longitude: 10.857805)),
Place(id: 0, type: .cyclist, title: "cyclist1", coordinate: CLLocationCoordinate2D(latitude: 35.785118 , longitude: 10.000871))
]
mapView.addAnnotations(places)
}
And your annotation view type would then use this type parameter:
class AnnotationView: MKMarkerAnnotationView {
override var annotation: MKAnnotation? { didSet { update(for: annotation) } }
override init(annotation: MKAnnotation?, reuseIdentifier: String?) {
super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
update(for: annotation)
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
func update(for annotation: MKAnnotation?) {
guard let annotation = annotation as? Place else { return }
switch annotation.type {
case .shop: markerTintColor = .blue
case .community: markerTintColor = .cyan
case .cyclist: markerTintColor = .green
case .circuit: markerTintColor = .red
}
}
}
This results in:

Changing the image and color of a mapView annotation

How would I change this code so that I could implement a color and a unique image for the respected group? Right now when I call the functions, they all produce the same generic red annotation. I would like for the groups to have different images and colors as opposed to multiple groups sharing the same annotations. How would I change this?
Here is my code.
import UIKit
import MapKit
struct PlacesOnMap {
var name: String
var latitude: Double
var longitude: Double
init(name: String, latitude: Double, longitude: Double) {
self.name = name
self.latitude = latitude
self.longitude = longitude
}
}
class MapViewController: UIViewController {
#IBOutlet var mapView: MKMapView!
var placesFirst = [PlacesOnMap(name: "place 1", latitude: 28.551700, longitude: -81.374800),
PlacesOnMap(name: "place 2", latitude: 28.553018, longitude: -81.374206),
PlacesOnMap(name: "place 3", latitude: 28.553019, longitude: -81.367839)]
var placesSecond = [PlacesOnMap(name: "place 1", latitude: 28.556969, longitude: -81.364319),
var placesThird = [PlacesOnMap(name: "place 1", latitude: 28.54693, longitude: -81.393071)]
PlacesOnMap(name: "place 2", latitude: 28.538523, longitude: -81.385399)]
override func viewDidLoad() {
super.viewDidLoad()
}
let markerView = MKMarkerAnnotationView()
func setupFirstPlacesAnnotations() {
let places = placesFirst.map { placeOnMap -> MKPointAnnotation in
let place = MKPointAnnotation()
place.coordinate = CLLocationCoordinate2D(latitude: placeOnMap.latitude, longitude: placeOnMap.longitude)
place.title = placeOnMap.name
return place
}
mapView.addAnnotations(places)
}
func setupSecondPlacesAnnotations() {
let places = placesSecond.map { placeOnMap -> MKPointAnnotation in
let place = MKPointAnnotation()
place.coordinate = CLLocationCoordinate2D(latitude: placeOnMap.latitude, longitude: placeOnMap.longitude)
place.title = placeOnMap.name
return place
}
mapView.addAnnotations(places)
}
func setupThirdPlacesAnnotations() {
let places = placesThird.map { placeOnMap -> MKPointAnnotation in
let place = MKPointAnnotation()
place.coordinate = CLLocationCoordinate2D(latitude: placeOnMap.latitude, longitude: placeOnMap.longitude)
place.title = placeOnMap.name
return place
}
mapView.addAnnotations(places)
}
extension MapViewController: CLLocationManagerDelegate, MKMapViewDelegate {
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
}
}
You can follow this tutorial and download the source code, you can see that it will tackle how to change the marker colors and images.
https://www.raywenderlich.com/7738344-mapkit-tutorial-getting-started

Launching Map App with Navigation after pressing a button

I am trying to open automatically the Maps App with Navigation, when pressing a Button.
My ViewController look like this:
import UIKit
import MapKit
class WhereViewController: UIViewController {
#IBOutlet weak var MapView: MKMapView!
#IBAction func navigateButtonHandler(_ sender: UIButton) {
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView,
calloutAccessoryControlTapped control: UIControl) {
let location = view.annotation as! Artwork
let launchOptions = [MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving]
location.mapItem().openInMaps(launchOptions: launchOptions)
}
}
override func viewDidLoad() {
super.viewDidLoad()
// set initial location in Honolulu
let initialLocation = CLLocation(latitude: 21.282778, longitude: -157.829444)
centerMapOnLocation(location: initialLocation)
//MapView.delegate = self
// show artwork on map
let artwork = Artwork(title: "King David Kalakaua",
locationName: "Waikiki Gateway Park",
discipline: "Sculpture",
coordinate: CLLocationCoordinate2D(latitude: 21.283921, longitude: -157.831661))
MapView.addAnnotation(artwork)
}
let regionRadius: CLLocationDistance = 1000
func centerMapOnLocation(location: CLLocation) {
let coordinateRegion = MKCoordinateRegionMakeWithDistance(location.coordinate,
regionRadius, regionRadius)
MapView.setRegion(coordinateRegion, animated: true)
}
}
And my Artwork Swift File looks like this:
import Foundation
import MapKit
import Contacts
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
}
// Annotation right callout accessory opens this mapItem in Maps app
func mapItem() -> MKMapItem {
let addressDict = [CNPostalAddressStreetKey: subtitle!]
let placemark = MKPlacemark(coordinate: coordinate, addressDictionary: addressDict)
let mapItem = MKMapItem(placemark: placemark)
mapItem.name = title
return mapItem
}
}
When i press the button, is doesn't work. Where is my mistake?
Hope you can help me.
I follow these Tutorial for the MapKit:
https://www.raywenderlich.com/548-mapkit-tutorial-getting-started
Thanks for your answer

Add Custom Image via a Subclass to Annotation and Add a Segue

I would like to add a custom image for a callout annotation via a subclass (previous questions did not include using a subclass)
Here is my code thus far:
Subclass named "Capital.swift"
import MapKit
import UIKit
class Capital: NSObject, MKAnnotation {
var title: String?
var coordinate: CLLocationCoordinate2D
var info: String
// here we would add the custom image
init(title: String, coordinate: CLLocationCoordinate2D, info: String) {
self.title = title
self.coordinate = coordinate
self.info = info
// add additional lines as needed
}
}
Here is my code for the ViewController.swift
import MapKit
import UIKit
class ViewController: UIViewController, MKMapViewDelegate {
#IBOutlet var mapView: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
let london = Capital(title: "London", coordinate: CLLocationCoordinate2D(latitude: 51.507222, longitude: -0.1275), info: "Home to the 2012 Summer Olympics.")
let oslo = Capital(title: "Oslo", coordinate: CLLocationCoordinate2D(latitude: 59.95, longitude: 10.75), info: "Founded over a thousand years ago.")
let paris = Capital(title: "Paris", coordinate: CLLocationCoordinate2D(latitude: 48.8567, longitude: 2.3508), info: "Often called the City of Light.")
let rome = Capital(title: "Rome", coordinate: CLLocationCoordinate2D(latitude: 41.9, longitude: 12.5), info: "Has a whole country inside it.")
let washington = Capital(title: "Washington DC", coordinate: CLLocationCoordinate2D(latitude: 38.895111, longitude: -77.036667), info: "Named after George himself.")
mapView.addAnnotations([london, oslo, paris, rome, washington])
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
let identifier = "Capital"
if annotation is Capital {
if let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) {
annotationView.annotation = annotation
return annotationView
} else {
let annotationView = MKPinAnnotationView(annotation:annotation, reuseIdentifier:identifier)
annotationView.isEnabled = true
annotationView.canShowCallout = true
let btn = UIButton(type: .detailDisclosure)
annotationView.rightCalloutAccessoryView = btn
return annotationView
}
}
return nil
}
Here we add the custom image to the annotationView
func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
let capital = view.annotation as! Capital
let placeName = capital.title
let placeInfo = capital.info
// Add custom image
// Add Segue
performSegue(withIdentifier: "segue1", sender: (capital.title, capital.coordinate, capital.info))
}
}
Thanks

How to add overlay path in MKMapView swift

I want to add a overlay path among multiple coordinates in mapview. I tried like below code, but it shows a error of "cannot invoke 'map' with an argument list of type ((CLLocation) -> CLLocationCoordinate2D)". Please let me know how can i fix this ?
My ViewController.swift file
import UIKit
import MapKit
class ViewController: UIViewController, MKMapViewDelegate{
#IBOutlet weak var mapView: MKMapView!
override func viewDidLoad() {
super.viewDidLoad()
//For Location 1
let location1 = CLLocationCoordinate2D(
latitude: 51.481188400000010000,
longitude: -0.190209099999947280
)
let annotation1 = MKPointAnnotation()
annotation1.coordinate = location1;
annotation1.title = "Chelsea"
annotation1.subtitle = "Chelsea"
let span = MKCoordinateSpanMake(0.15, 0.15)
let region1 = MKCoordinateRegion(center: location1, span: span)
mapView.setRegion(region1, animated: true)
mapView.addAnnotation(annotation1)
//For Location 2
let location2 = CLLocationCoordinate2D(
latitude: 51.554947700000010000,
longitude: -0.108558899999934510
)
let annotation2 = MKPointAnnotation()
annotation2.coordinate = location2;
annotation2.title = "Arsenal"
annotation2.subtitle = "Arsenal"
let region2 = MKCoordinateRegion(center: location1, span: span)
mapView.setRegion(region2, animated: true)
mapView.addAnnotation(annotation2)
var locations = [CLLocation(latitude: 51.481188400000010000, longitude: -0.190209099999947280), CLLocation(latitude: 51.554947700000010000,longitude: -0.108558899999934510)]
//This line shows error
var coordinates = locations.map({(location: CLLocation) -> CLLocationCoordinate2D in return location.coordinate})
var polyline = MKPolyline(coordinates: &coordinates, count: locations.count)
mapView.addOverlay(polyline)
}
func mapView(mapView: MKMapView!, rendererForOverlay overlay: MKOverlay!) -> MKOverlayRenderer! {
if overlay is MKPolyline {
var polylineRenderer = MKPolylineRenderer(overlay: overlay)
polylineRenderer.strokeColor = UIColor.blueColor()
polylineRenderer.lineWidth = 5
return polylineRenderer
}
return nil
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
This should work:
var coordinates = locations.map {
location in
return location.coordinate
}
One-liner:
var coordinates = locations.map { $0.coordinate }
The problem with your code was that locations is a variable of type [CLLocation!] (note the exclamation mark here), but you are declaring its elements as CLLocation (without the !) in the closure:
(location: CLLocation) -> CLLocationCoordinate2D

Resources