Swift 3 - Custom MKPointAnnotation Image

This is my code, and I want to add custom output (.png file) instead of red output. I tried to use MKPinAnnotationView and MKAnnotationView, but I could not add coordinates, subtitles and title. I am new to iOS development.

override func viewDidLoad() { super.viewDidLoad() // Handle the text field's user input through delegate callbacks. commentTextField.delegate = self coreLocationManager.delegate = self //desired accuracy is the best accuracy, very accurate data for the location coreLocationManager.desiredAccuracy = kCLLocationAccuracyBest //request authorization from the user when user using my app coreLocationManager.requestWhenInUseAuthorization() coreLocationManager.startUpdatingLocation() dbRef = FIRDatabase.database().reference() struct Location { let title: String let latitude: Double let longitude: Double let subtitle: String } // Locations array let locations = [ Location(title: "Dio Con Dio", latitude: 40.590130, longitude: 23.036610,subtitle: "cafe"), Location(title: "Paradosiako - Panorama", latitude: 40.590102, longitude: 23.036180,subtitle: "cafe"), Location(title: "Veranda", latitude: 40.607740, longitude: 23.103044,subtitle: "cafe") ] for location in locations { let annotation = MKPointAnnotation() annotation.title = location.title annotation.coordinate = CLLocationCoordinate2D(latitude: location.latitude, longitude: location.longitude) annotation.subtitle = location.subtitle map.addAnnotation(annotation) } } 
+6
source share
6 answers

You must specify your view controller as a delegate for the map view (either in IB or programmatically in viewDidLoad and then (a) indicate that you comply with the MKMapViewDelegate protocol, and (b) implement mapView(_:viewFor:) :

 extension ViewController: MKMapViewDelegate { func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { let identifier = "MyPin" if annotation is MKUserLocation { return nil } var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) if annotationView == nil { annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: identifier) annotationView?.canShowCallout = true annotationView?.image = UIImage(named: "custom_pin.png") // if you want a disclosure button, you'd might do something like: // // let detailButton = UIButton(type: .detailDisclosure) // annotationView?.rightCalloutAccessoryView = detailButton } else { annotationView?.annotation = annotation } return annotationView } } 

For more information, see Location and Map Programming Guide: Creating Annotations from Your Delegate Object . Code snippets in Objective-C, but it describes the main process.

+12
source

Finally, I did it this way myself!

ViewController.swift

  // // ViewController.swift // // Created by Alexandros Andreadis on 19/04/2017. // Copyright © 2017 Alexandros Andreadis. All rights reserved. // import UIKit import MapKit import CoreLocation import FirebaseDatabase class RateViewController: UIViewController, UITextFieldDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate, CLLocationManagerDelegate, MKMapViewDelegate{ let pin = UIImage(named: "pin") func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { if let annotation = annotation as? Locations{ if let view = mapView.dequeueReusableAnnotationView(withIdentifier: annotation.identifier){ return view }else{ let view = MKAnnotationView(annotation: annotation, reuseIdentifier: annotation.identifier) view.image = pin view.isEnabled = true view.canShowCallout = true //view.leftCalloutAccessoryView = UIImageView(image: pin) return view } } return nil } override func viewDidLoad() { super.viewDidLoad() mapView.delegate = self mapView.addAnnotations(locations) } } 

Locations.swift

 // // Locations.swift // // Created by Alexandros Andreadis on 10/05/2017. // Copyright © 2017 Alexandros Andreadis. All rights reserved. // import UIKit import MapKit class Locations: NSObject, MKAnnotation { // required coordinate, title, and the reuse identifier for this annotation var identifier = "locations" var title: String? var coordinate: CLLocationCoordinate2D //initializer taking a name, a latitude and longitude to populate the title and coordinate for each instance of this object init(name:String,lat:CLLocationDegrees,long:CLLocationDegrees){ title = name coordinate = CLLocationCoordinate2DMake(lat, long) } } // Creating the list of the places that will be pinned in map class LocationList: NSObject { var Location = [Locations]() override init(){ Location += [Locations(name: "Dio Con Dio", lat: 40.590130, long: 23.036610)] Location += [Locations(name: "Paradosiako - Panorama", lat: 40.590102, long:23.036180)] Location += [Locations(name: "Veranda", lat: 40.607740, long: 23.103044)] Location += [Locations(name: "Markiz", lat: 40.634252, long: 22.936276)] Location += [Locations(name: "Moi Lounge Bar", lat: 40.653481, long: 22.994131)] Location += [Locations(name: "Boulevard Lounge Bar", lat: 40.658462, long: 22.983198)] Location += [Locations(name: "Ernést Hébrard", lat: 40.631829, long: 22.941014)] Location += [Locations(name: "Tribeca - All Day & Night Bar", lat: 40.631029, long: 22.942396)] } } 
+2
source
 func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? { let identifier = "MyPin" if annotation.isKindOfClass(MKUserLocation) { return nil } let detailButton: UIButton = UIButton(type: UIButtonType.DetailDisclosure) if let annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier(identifier) { annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: "pin") annotationView.canShowCallout = true annotationView.image = UIImage(named: "custom_pin.png") annotationView.rightCalloutAccessoryView = detailButton } else { annotationView.annotation = annotation } return annotationView } 
0
source

use this method: optional func mapView (_ mapView: MKMapView, didAdd views: [MKAnnotationView])

works fine for me (my environment: Xcode 9.4.1 and iOS 11.4.1)

Example:

 func mapView(_ mapView: MKMapView, didAdd views: [MKAnnotationView]) { //views[0] = just added MKAnnotationView let pic = UIImage(named: "abc.jpg") views[0].image = pic views[0].layer.cornerRadius = (views[0].frame.size.width) / 2 views[0].clipsToBounds = true print("fafafjejowfjpeawijoefaw") } 
0
source

I added this way

  func mapView(_ mapView: MKMapView, didAdd views: [MKAnnotationView]) { let sourceView = views.first sourceView?.image = UIImage(named: "Bus") let destinationView = views.last destinationView?.image = UIImage(named: "Home") } 
0
source

SWIFT 5

 let pointAnnotation = MKPointAnnotation() override func viewDidLoad() { mapVw.delegate = self pointAnnotation.coordinate = CLLocationCoordinate2D(latitude: yourLatitude, longitude:yourLongitude) mapVw.addAnnotation(pointAnnotation) } // MARK:- MapView Delegate func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { if annotation is MKUserLocation { return nil; }else{ let pinIdent = "Pin"; var pinView: MKAnnotationView? if let dequeuedView = mapView.dequeueReusableAnnotationView(withIdentifier: pinIdent) { dequeuedView.annotation = annotation; pinView = dequeuedView; } else { pinView = MKAnnotationView(annotation: annotation, reuseIdentifier: pinIdent); pinView?.image = UIImage(named: "yourImage") } return pinView; } } 
0
source

All Articles