2

The only way I have found to differentiate MKPolygons is by using the MKPolygon.version(Int: Int) type property. I can set this to 1,2,3 etc. and give each one a different color (for example). I wanted to extend MKPolygon to add a tag but Swift extensions cannot add stored properties. I am not comfortable using MKPolygon.version (should I be?). Is there a better way?

  • Try subclassing MKPolygon – David Berry Aug 15 '16 at 14:22
  • Worked a treat! Thanks @DavidBerry . I actually created a... static var identifier = "Blue" etc. and then in the mapView(_:rendererForOverlay:) method I used ... if let overlay = overlay as? MyPolygon && MyPolygon.identifier == "Blue". can now add multiple polygons of different colors and props. – KeithRussell Aug 16 '16 at 17:58

2 Answers2

3

Subclass MKPolygon and put your custom properties there:

class MyPolygon: MKPolygon {
    var identifier: String?
}

Then in the mapView(_:rendererForOverlay:) method, convert it to your class:

func mapView(_ mapView: MKMapView, rendererForOverlay overlay: MKOverlay) -> MKOverlayRenderer {
    if let overlay = overlay as? MyPolygon {
        let identifier = overlay.identifier
        // Do stuffs....
    }
}

(I'm not near Xcode and Apple's documentation site is back and forth between Swift 2 and Swift 3 so some function declarations may not match)

Code Different
  • 90,614
  • 16
  • 144
  • 163
  • If you can provide a default value or use an optional this is fine. Otherwise you will have to define initializers for this, which is not so straightforward given MKPolygon has only convenience initializers. I ended up subclassing MKOverlay to add my fields. When asked for that overlay's renderer, I then generate a MKPolygonRenderer. – Jason Campbell Apr 29 '21 at 08:56
1

Hey I know this was a while back but for anyone else wondering, you totally do not need to subclass MKPolygon to achieve this. I tried to do that and ran into some problems. I'm sure they could've been solved somehow or another, but my solution was to make a dictionary of type [Int : String]. When you initially create the polygon, use its hashValue as the dictionary key and insert whatever unique id you want (you could also use [Int : Int] or any number of other types) . Then later when you need to figure out which polygon it is, just throw that hash value back into the dictionary and voila, you have your unique id. In case this isn't clear:

//vars/lets section:
var hashValueToUniqueID : [Int : String] = [:]

//section where polygons are generated
polygon: MKPolygon = generatePolygon() //this is a made up function
hashValueToUniqueID[polygon.hashValue] = "1234"

//section where you access polygons
var uniqueIDToFind = "1234"
if let overlays = mapView.overlays as? [MKPolygon] {
    for overlayItem in overlays {
        if hashValueToUniqueID[polygon.hashValue] == uniqueIDToFind {
            return polygon
        }
    }
}

Note that if you delete all the polygons and recreate them you should reinitialize the dictionary.

Jake
  • 113
  • 7