lurning too koad
lurning too koad

Reputation: 2974

How do I pass in custom properties from Mapbox annotation to its callout view?

I subclassed MGLAnnotation to add an extra property var tags like so:

class MasterMapAnnotation: NSObject, MGLAnnotation {

    var coordinate: CLLocationCoordinate2D
    var title: String?
    var subtitle: String?
    var tags: String?

    init(coordinate: CLLocationCoordinate2D, title: String?, subtitle: String?, tags: String?) {

        self.coordinate = coordinate
        self.title = title
        self.subtitle = subtitle
        self.tags = tags

    }

}


Here is that annotation passed into the map:

let annotation = MasterMapAnnotation(coordinate: CLLocationCoordinate2D(latitude: 50.0, longitude: 50.0), title: "Numero Uno", subtitle: "Numero Uno subtitle", tags: "#tag1 #tag2")
mapView.addAnnotation(annotation)


The mapView delegate calls a custom callout view:

func mapView(_ mapView: MGLMapView, calloutViewFor annotation: MGLAnnotation) -> MGLCalloutView? {

    return MasterMapCalloutView(representedObject: annotation)

}


So in the callout view subclass (below), how do I access this new property tags?

class MasterMapCalloutView: UIView, MGLCalloutView {

    var representedObject: MGLAnnotation
    let dismissesAutomatically: Bool = false
    let isAnchoredToAnnotation: Bool = true
    lazy var leftAccessoryView = UIView()
    lazy var rightAccessoryView = UIView()
    weak var delegate: MGLCalloutViewDelegate?

    required init(representedObject: MGLAnnotation) {
        self.representedObject = representedObject
        super.init(frame: .zero)
    }

    required init?(coder decoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    // callout view delegate: present callout
    func presentCallout(from rect: CGRect, in view: UIView, constrainedTo constrainedView: UIView, animated: Bool) {

        if !representedObject.responds(to: #selector(getter: MGLAnnotation.title)) {
            return
        }

        view.addSubview(self)

        let title = representedObject.title
        let tags = representedObject.tags // how to access this?

    }

}


The problem is obviously that the subclass (MasterMapAnnotation) possesses the custom tags property, not its superclass (MGLAnnotation) but I don't know how to either (a) set the representedObject as MasterMapAnnotation or (b) simply access the MasterMapAnnotation custom property without reconfiguring the protocol.

Upvotes: 1

Views: 314

Answers (1)

Marcus
Marcus

Reputation: 2321

I may be missing something, but surely you just check if you can cast the MGLAnnotation object to MasterMapAnnotation:

guard let masterAnnotation : MasterMapAnnotation = representedObject as? MasterMapAnnotation else { return }

let tags : String? = masterAnnotation.tags

// etc

Obviously there are other ways to control the flow other than using guard, but I hope you get the gist.

Upvotes: 3

Related Questions