Is there a way to add an ID or something, that i am able to set custom marker images?
I have multiple markers with numbers, and i need that every new marker has another image.
For example:
marker1 - marker_1_image
marker2 - marker_2_image
Atm i am only able to set 1 image (globaly) to all markers:
func mapView(mapView: MGLMapView, imageForAnnotation annotation: MGLAnnotation) -> MGLAnnotationImage? {
var annotationImage = mapView.dequeueReusableAnnotationImageWithIdentifier("place")
if annotationImage == nil {
var image = UIImage(named: "marker_1")!
image = image.imageWithAlignmentRectInsets(UIEdgeInsetsMake(0, 0, image.size.height/2, 0))
annotationImage = MGLAnnotationImage(image: image, reuseIdentifier: "place")
}
return annotationImage
}
Any ideas? Or can i subclass MGLAnnotation and use that for all delegate methods?
You could subclass and add a userInfo
property (as in this answer), or you could use the existing title/subtitle properties:
func mapView(mapView: MGLMapView, imageForAnnotation annotation: MGLAnnotation) -> MGLAnnotationImage? {
// get the custom reuse identifier for this annotation
let reuseIdentifier = reuseIdentifierForAnnotation(annotation)
// try to reuse an existing annotation image, if it exists
var annotationImage = mapView.dequeueReusableAnnotationImageWithIdentifier(reuseIdentifier)
// if the annotation image hasn‘t been used yet, initialize it here with the reuse identifier
if annotationImage == nil {
// lookup the image for this annotation
let image = imageForAnnotation(annotation)
annotationImage = MGLAnnotationImage(image: image, reuseIdentifier: reuseIdentifier)
}
return annotationImage
}
// create a reuse identifier string by concatenating the annotation coordinate, title, subtitle
func reuseIdentifierForAnnotation(annotation: MGLAnnotation) -> String {
var reuseIdentifier = "\(annotation.coordinate.latitude),\(annotation.coordinate.longitude)"
if let title = annotation.title where title != nil {
reuseIdentifier += title!
}
if let subtitle = annotation.subtitle where subtitle != nil {
reuseIdentifier += subtitle!
}
return reuseIdentifier
}
// lookup the image to load by switching on the annotation's title string
func imageForAnnotation(annotation: MGLAnnotation) -> UIImage {
var imageName = ""
if let title = annotation.title where title != nil {
switch title! {
case "blah":
imageName = "blahImage"
default:
imageName = "defaultImage"
}
}
// ... etc.
return UIImage(named: imageName)!
}
You’ll want to make the image loading more robust and customize the specificity of the reuse identifier string, but this should generally work.
Carrying on from my initial answer, the recommended way to do this is to simply create your own annotation class that includes the properties you need.
You should implement the MGLAnnotation
protocol or subclass and add a userInfo
property. Both techniques are demonstrated in the official example, and here’s the former:
Define your custom annotation class:
// MGLAnnotation protocol reimplementation
class CustomPointAnnotation : NSObject, MGLAnnotation {
// As a reimplementation of the MGLAnnotation protocol, we have to add mutable coordinate and (sub)title properties ourselves.
var coordinate: CLLocationCoordinate2D
var title: String?
var subtitle: String?
// Custom properties that we will use to customize the annotation's image.
var image: UIImage?
var reuseIdentifier: String?
init(coordinate: CLLocationCoordinate2D, title: String?, subtitle: String?) {
self.coordinate = coordinate
self.title = title
self.subtitle = subtitle
}
}
And use it in your view controller:
override func viewDidLoad() {
// Do your map loading, remembering to set the map delegate.
let point = CustomPointAnnotation(coordinate: CLLocationCoordinate2DMake(0, 0),
title: "Custom Point Annotation",
subtitle: nil)
// Set the custom `image` and `reuseIdentifier` properties, later used in the `mapView:imageForAnnotation:` delegate method.
point.reuseIdentifier = "someIdentiferForYourImage"
point.image = UIImage(named: "someImage")
mapView.addAnnotation(point)
}
func mapView(mapView: MGLMapView, imageForAnnotation annotation: MGLAnnotation) -> MGLAnnotationImage? {
if let point = annotation as? CustomPointAnnotation,
image = point.image,
reuseIdentifier = point.reuseIdentifier {
if let annotationImage = mapView.dequeueReusableAnnotationImageWithIdentifier(reuseIdentifier) {
// The annotatation image has already been cached, just reuse it.
return annotationImage
} else {
// Create a new annotation image.
return MGLAnnotationImage(image: image, reuseIdentifier: reuseIdentifier)
}
}
// Fallback to the default marker image.
return nil
}
// set different images for multiple pins.
func mapView(mapView: MGLMapView, imageForAnnotation annotation: MGLAnnotation) -> MGLAnnotationImage?
{
var annotationImage : MGLAnnotationImage? = nil
//seems to be a double optional! String??
var title = ""
var subTitle = ""
//--------------------------------------------------
//TITLE
//--------------------------------------------------
if let titleOpt = annotation.title{
if let title_ = titleOpt{
title = title_
}
}
//--------------------------------------------------
//SUBTITLE
//--------------------------------------------------
if let subtitleOpt = annotation.subtitle{
if let subtitle_ = subtitleOpt{
subTitle = subtitle_
}
}
//---------------------------------------------------------------------
if title == "" {
}else{
if title == "Assault" {
// let imageOut = (title , iconColor: UIColor.appColorFlat_TahitiGold_Orange())
annotationImage = MGLAnnotationImage(image:UIImage(named:"Assault")!, reuseIdentifier: title)
}
else if title == "Rape" {
//let imageOut = self.textToImage(title , iconColor: UIColor.appColorButtonPink())
annotationImage = MGLAnnotationImage(image: UIImage(named:"Rape")!, reuseIdentifier: title)
}
else if title == "Robbery" {
//let imageOut = self.textToImage(title , iconColor: UIColor.appColorButtonPink())
annotationImage = MGLAnnotationImage(image: UIImage(named:"Robbery")!, reuseIdentifier: title)
}
else if title == "Violet Crime Murder" {
//let imageOut = self.textToImage(title , iconColor: UIColor.appColorButtonPink())
annotationImage = MGLAnnotationImage(image: UIImage(named:"Violet Crime Murder")!, reuseIdentifier: title)
}
else if title == "Poor Roads" {
//let imageOut = self.textToImage(title , iconColor: UIColor.appColorButtonPink())
annotationImage = MGLAnnotationImage(image: UIImage(named:"Poor Roads")!, reuseIdentifier: title)
}
else if title == "Unsafe Neighbourhoods" {
//let imageOut = self.textToImage(title , iconColor: UIColor.appColorButtonPink())
annotationImage = MGLAnnotationImage(image: UIImage(named:"Unsafe Neighbourhoods")!, reuseIdentifier: title)
}
else if title == "Arson" {
//let imageOut = self.textToImage(title , iconColor: UIColor.appColorButtonPink())
annotationImage = MGLAnnotationImage(image: UIImage(named:"Arson")!, reuseIdentifier: title)
}
else if title == "Poor Lighting" {
//let imageOut = self.textToImage(title , iconColor: UIColor.appColorButtonPink())
annotationImage = MGLAnnotationImage(image: UIImage(named:"Poor Lighting")!, reuseIdentifier: title)
}
else{
// let imageOut = self.textToImage(title ,iconColor: UIColor.appColorCYAN())
annotationImage = MGLAnnotationImage(image: UIImage(named:"Default")!, reuseIdentifier: title)
}
}
return annotationImage
}