Search code examples
objective-cxcodemkmapviewmkannotationmkannotationview

A simpler way to code multiple MKAnnotations?


This code is from the MapCallouts demo. Say I had hundreds of different annotations. The way that Apple has done it, it would result in a lot of code duplication.

I want to access the annotation properties of the instance of the class that triggered the delegate, no matter which class instance triggered it.

Is there a simpler way than writing if statements to handle each annotation and have one universal method?

- (MKAnnotationView *)mapView:(MKMapView *)theMapView viewForAnnotation:(id <MKAnnotation>)annotation
    {
        // if it's the user location, just return nil.
        if ([annotation isKindOfClass:[MKUserLocation class]])
            return nil;

        // handle our two custom annotations
        //
        if ([annotation isKindOfClass:[BridgeAnnotation class]]) // for Golden Gate Bridge
        {
            //do something   
        }
        else if ([annotation isKindOfClass:[SFAnnotation class]])   // for City of San Francisco
        {
            //do something
        }

        return nil;
    }

Solution

  • You could have all your annotation classes provide some common method, like -annotationView. You might derive all the annotation classes from a common superclass, or just create a protocol. Then, check that the annotation actually responds to the selector, or is a subclass of your common class, and ask it for it's view:

    if ([annotation respondsToSelector:@selector(annotationView)]) {
        return [annotation annotationView];
    }
    

    or

    if ([annotation isKindOfClass:[AbstractAnnotation class]]) {
        return [annotation annotationView];
    }
    

    One reason not to do that is that the objects you use as annotations are often parts of your data model, and they may not have any business knowing anything about annotation views. It's one thing to be able to provide a title, subtitle, and location; providing an actual instance of a view is often outside the scope of what a model object should do.

    Keep in mind that annotation views usually don't do too much other than display a picture and provide the left and right accessories for the callout view. Is it really likely that you'll need hundreds of different annotation view subclasses? Or can you use a common annotation view for all your annotations, and just configure them differently (such as by changing the annotation view's image)?