How can I add two pins with different colors? One with “Red” and the other one with “Purple” color.
Is that using our MBS Plugin classes?
Yes. I use example: “MapKit Custom Icons example” from the folder “MacFramework/MapKit”. In this example I can change the pin color only for all visible pins. I need two or more pins with different colors at the same time.
For our plugin the MKPinAnnotationViewMBS class has a pinTintColor field to pick any color you like for the .
You create a new pin annotation class and add it to the viewForAnnotation
Alternatively make it dependent on some other property, so in the map’s ViewForAnnotation instead of
Select Case popIconTypeSelection.Text
Select Case annotation.title Case "Start" Return GetViewForPin( annotation, "Red Pin", "Red Pin", "red", 1000 ) Case "Finish" Return GetViewForPin( annotation, "Green Pin", "Green Pin", "green", 1000 ) Case "Water" Return GetViewForPin( annotation, "Purple Pin", "Purple Pin", "purple", 1000 )
But it would be better to use a custom pin annotation and give it a property that you can use for the selector like I do for the custom annotations Car and Driver (and note that in GetViewForCustomAnnotation you need to cast the annotation).
Note that GetViewForPin and GetViewForCustomAnnotation are just convenience functions to simplify the code.
that looks good. Have you an example project for this?
One of the things you have to understand about using MapKit is that you have annotations (very simple “cheap” objects) and views (very expensive memory-hungry objects - that’s why the map reuses views as much as possible with the help of a limited pool of cached views and the reuse identifier).
There might also be a lot of other annotations on your map other than the ones you are now interested in.
The map passes ONLY the annotations currently visible into ViewForAnnotation to get a view. By default that is a red pin.
If you want ANYTHING other than a red pin (eg a green pin), then you need to return a customised view.
If you also want different pin colors (or icons) aka different views then you need to be able to determine which view you need. So you need SOME property that you can select for.
That property could be the Title (like “Start”, “Finish”, “Water”) or SubTitle property, but it is MUCH better to make a new Annotation class and give it a property to select for as Title and SubTitle are usually shown when you click a pin - and that massively restricts what you can put in there.
So add a new class cLocation, set its super to MKPointAnnotationMBS, and give it a property
selector as String
You’ll probably also want to keep track of all your locations so add an array to the window:
Locations() as cLocation
Now you need to define a custom view for your Location annotation objects. In the simplest case you could just create a MKPinAnnotationViewMBS and change its properties, so in ViewForAnnotation you do:
If annotation IsA cLocation Then dim Location as cLocation = cLocation(annotation) select case Location.selector case "purple pin" // create a variable of type AnnotationView and try to assign a view // with the same reuseIdentifier to it from the reuse pool of views Dim viewForPin As MKPinAnnotationViewMBS = MKPinAnnotationViewMBS(mapView.dequeueReusableAnnotationViewWithIdentifier(reuseIdentifier)) // either a suitable annotation view is returned, or Nil // so test for Nil: // if it is Nil then we have a view that we can return // if not we create a new view to customise and return If view <> Nil Then Return view Else // create a new one view = New MKPinAnnotationViewMBS( annotation, "purple pin" ) End If // set up display priority view.displayPriority = displayPriority // set up collision mode view.collisionMode = 1 // circular // set up clustering view.clusteringIdentifier = "Purple Pin Cluster" // set up callout view.canShowCallout = True view.pinTintColor = MKPinAnnotationViewMBS.PurplePinColor // hook the annotation to the view view.annotation = annotation Return view case "pink pin" … End Select
But if you want to customise the view even more (eg have an image) then you should not use an MKPinAnnotationViewMBS but an MKAnnotationViewMBS.
Btw if you have xDev I wrote a series about MapKit with 10 articles - I would recommend to read part 6 in xDev 18.5 (Sep/Oct 2020 issue)
I would recommend to read part 6 in xDev 18.5 (Sep/Oct 2020 issue) and part 7 in xDev 18.6 (Nov/Dec 2020 issue)
Ooops - that should of course be
Dim view As MKPinAnnotationViewMBS = MKPinAnnotationViewMBS(mapView.dequeueReusableAnnotationViewWithIdentifier(reuseIdentifier))
P.S. Searching for info you’ll probably need to look at Apple’s documentation and Swift code. There is one difference you should be aware of.
Xojo has classes and interfaces (aka method definitions). The important difference is that classes are in a hierarchy (eg superclass and subclass), whereas interfaces cut across hierarchies (any class can implement an interface).
In Swift EVERYTHING is an object (even integers), and an annotation is a protocol, what Xojo calls an interface. But in Swift protocols can have properties too - so a Swift protocol with properties cannot be implemented as an interface in Xojo (as that only allows method definitions - which is a shame). Instead the annotation protocol in Swift’s MapKit is implemented as a class in Xojo which means your annotations must be subclasses of it …