Set MapKit pins with different colors - ios

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:

Related

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

Show JSON data in Google map custom info view

I got some markers in Google Maps and show them with JSON in on map. There is a custom info view as UIView to show some information in it but I can't show json in custom info view labels. Also markers work correctly. I try to use data provider to save data and use it in didTapMarker Method but I can't handle it.
This is the viewController:
class maappp: UIViewController, GMSMapViewDelegate, CLLocationManagerDelegate {
#IBOutlet weak var mapView: GMSMapView!
var tappedMarker = GMSMarker()
var infoWindow = CustomInfoWindow(frame: CGRect(x: 0, y: 0, width: 300, height: 165))
struct Lugares : Codable {
let latitude : String?
let longitude : String?
let name : String?
let address : String?
let phone : String?
}
private var marcadores = [Lugares]()
override func viewDidLoad() {
super.viewDidLoad()
self.mapView.delegate = self
let cameraZone = GMSCameraPosition.camera(withLatitude: 35.688272, longitude: 51.386217, zoom: 11.0)
mapView.camera = cameraZone
let mapView = GMSMapView.map(withFrame: self.mapView.frame, camera: cameraZone)
mapView.isMyLocationEnabled = true
mapView.settings.myLocationButton = true
mapView.settings.compassButton = true
mapView.settings.indoorPicker = true
mapView.settings.scrollGestures = true
mapView.settings.zoomGestures = true
self.tappedMarker = GMSMarker()
guard let mapUrl = URL(string: LOCATION_BASE_URL) else { return }
URLSession.shared.dataTask(with: mapUrl) { (data, response, error) in
if error == nil {
do {
self.marcadores = try JSONDecoder().decode([Lugares].self, from: data!)
DispatchQueue.main.async {
for state in self.marcadores {
print(state.latitude!, state.name!)
let lat = Double(state.latitude!)
let long = Double(state.longitude!)
//markers work correctly
let marker = GMSMarker()
marker.position = CLLocationCoordinate2D(
latitude: lat!,
longitude: long!)
marker.map = self.mapView
marker.icon = UIImage(named: "place")
}
}
} catch let jsonError{
print("An error occurred + \(jsonError)")
}
}
}.resume()
}
class func instanceFromNib() -> CustomInfoWindow {
return UINib(nibName: "CustomInfoWindow", bundle: nil).instantiate(withOwner: nil, options: nil)[0] as! CustomInfoWindow }
question is how to put recived data from json in 2 below label and
show theme when clicked on a marker
func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
let location = CLLocationCoordinate2D(latitude: marker.position.latitude, longitude: marker.position.longitude)
self.tappedMarker = marker
self.infoWindow.removeFromSuperview()
self.infoWindow = maappp.instanceFromNib()
self.infoWindow.nameLbl.text = ""
self.infoWindow.AddressLbl.text = ""
self.infoWindow.center = mapView.projection.point(for: location)
self.view.addSubview(self.infoWindow)
return false
}
func mapView(_ mapView: GMSMapView, didChange position: GMSCameraPosition) {
let location = CLLocationCoordinate2D(latitude: tappedMarker.position.latitude, longitude: tappedMarker.position.longitude)
infoWindow.center = mapView.projection.point(for: location)
}
func mapView(_ mapView: GMSMapView, didTapAt coordinate: CLLocationCoordinate2D) {
infoWindow.removeFromSuperview() }
func mapView(_ mapView: GMSMapView, markerInfoWindow marker: GMSMarker) -> UIView? {
return UIView()
}
}
This is the JSON array:
[
{
name: "name1",
longitude: "51.395836",
latitude: "35.776441",
address: "address1",
phone : "57767000"
},
{
name: "name2",
longitude: "51.247014",
latitude: "35.753798",
address: "address2",
phone : "66341933"
},
{
name: "name3",
longitude: "51.243728",
latitude: "35.755143",
address: "address3",
phone : "88887588"
}
]

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

Why are my annotations not appearing in my map view?

I have created a set of "IssueLocation"'s, a class which conforms to the MKAnnotation protocol. Why are my annotations (built from API JSON data) not appearing in my map view ?
Here is the code behind it all:
Class code:
class IssueLocation: NSObject, MKAnnotation {
var locationName: String
var campusName: String
var latitude: Double
var longitude: Double
var coordinate: CLLocationCoordinate2D
init(locationName: String, campusName: String, latitude: Double, longitude: Double, coordinate: CLLocationCoordinate2D) {
self.locationName = locationName
self.campusName = campusName
self.latitude = latitude
self.longitude = longitude
self.coordinate = coordinate
super.init()
}
var subtitle: String? {
if (latitude == 44.22438242146097) {
return "West Campus"
} else {
return "Main Campus"
}
}
var title: 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 = locationName
return mapItem
}
}
Creating a set of IssueLocations:
func populateMapObjects() {
if populatingMapObjects {
return
}
populatingMapObjects = true
self.loadingIndicator.startAnimating()
var index = 0
Alamofire.request(GWNetworking.Router.MapObjects).responseJSON() { response in
if let JSON = response.result.value {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0)) {
/* Making an array of all the node IDs from the JSON file */
if (JSON .isKindOfClass(NSArray)) {
for _ in JSON as! [Dictionary<String,AnyObject>] {
if let issueLocation: IssueLocation = IssueLocation(locationName: "Center of the universe", campusName: "Queen's University", latitude: 44.22661586877309, longitude: -76.49380087852478, coordinate: CLLocationCoordinate2D(latitude: 44.22661586877309, longitude: -76.49380087852478)) {
if let locationName = JSON[index]["name"] as? String {
issueLocation.locationName = locationName
}
if let latitude = JSON[index]["coordinates"]!![1] as? Double {
issueLocation.latitude = latitude
}
if let longitude = JSON[index]["coordinates"]!![0] as? Double {
issueLocation.longitude = longitude
}
issueLocation.coordinate = CLLocationCoordinate2D(latitude: issueLocation.latitude, longitude: issueLocation.longitude)
index = index+1
self.mapObjects.append(issueLocation)
}
}
}
dispatch_async(dispatch_get_main_queue()) {
self.loadingIndicator.stopAnimating()
self.populatingMapObjects = false
print(self.mapObjects.count)
}
}
}
}
}
And finally, this is where I try to add the annotations to the map view:
func loadObjectsIntoMapView() {
for mapObject in mapObjects {
let temporaryMapAnnotation = IssueLocation(locationName: mapObject.locationName, campusName: "Main Campus", latitude: mapObject.latitude, longitude: mapObject.longitude, coordinate: mapObject.coordinate)
if (temporaryMapAnnotation.longitude < -76.50921821594238) {
temporaryMapAnnotation.campusName = "West Campus"
}
self.mapView.addAnnotation(temporaryMapAnnotation)
}
}
Move loadObjectsIntoMapView() into this block:
dispatch_async(dispatch_get_main_queue()) {
self.loadingIndicator.stopAnimating()
self.populatingMapObjects = false
print(self.mapObjects.count)
}
Calling loadObjectsIntoMapView() in viewDidLoad will have it execute immediately and the data has not come down from the server yet so you will have no mapObject in mapObjects hence no annotations.

Annotations won't appear on MapView

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

Resources