khunshan
khunshan

Reputation: 2862

How to make a custom annotation using Map Kit in iOS?

I want to make a MapKit annotation with 3 images and 5 buttons like when I click on the annotation pin, the popup information box appears with a title and a subtitle. I can put images and buttons on left and right by using setRightCalloutAccessoryView but how can I make a completely customized view?

Upvotes: 0

Views: 276

Answers (1)

Mark Semsel
Mark Semsel

Reputation: 7155

There is a tutorial on this, available at:
http://www.codigator.com/tutorials/advanced-mapkit-tutorial-for-ios-custom-callout/
I'll describe an overview below.

If the viewcontroller containing your mapView conforms to the MKMapViewDelegate protocol, you can respond to the didSelectAnnotationView method. This allows us to create a custom view with whatever controls we need. Not shown in this example is the positioning of the custom view:

- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view {
    // note that we don't do this if the selected annotation is for the user location
    if(![view.annotation isKindOfClass:[MKUserLocation class]]) {

        UIView * myCustomView = [self createMyCustomView];
       [view addSubview:myCustomView];

        // you can also load a view from a xib file.  
        // If there are going to be a lot of annotations, I'd probably load a xib
        // to a local view property during the parent view controller's viewDidLoad,
        // and simply refresh the contents of that view whenever this is called.
    }
}

// Build a view hierarchy programmatically.
- (UIView *) createMyCustomView {

    UIView * myView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
    UIImageView * myImage = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 50, 50)];
    [myImage setImage:[UIImage imageNamed:@"some_image"]];
    [myView addSubview:myImage];

    UIButton * thisButton = [[UIButton alloc] initWithFrame:CGRectMake(50,50, 50, 10)];
    [thisButton.titleLabel setText:@"My Button"];
    [thisButton addTarget:self action:@selector(handleMyButton:) forControlEvents:UIControlEventTouchUpInside];
    [myView addSubview:thisButton];

    // etc.

    return myView;

}

You should also therefore respond to the didDeselectAnnotationView protocol:

- (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view
{
    for (UIView *subview in view.subviews ){
        [subview removeFromSuperview];
    }
}

Upvotes: 1

Related Questions