views:

2658

answers:

3

I'm trying to add an image behind a MKPinAnnotationView. Seems like it should be rather easy to just do this in here:

- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views {
 for (MKAnnotationView *aView in views)
  [[aView superview] addSubview:imageView];
}

But the problem I am having in doing that is that the child subview to the pin will render on top of it not BEHIND it.

I have also tried:

 for (MKAnnotationView *aView in views)
  [[aView superview] insertSubview:imageView atIndex:1];

The problem with this is that, while it IS behind the pin, as soon as the map is repositioned, the image floats off the screen.

Any suggestions? Thanks

+2  A: 

Create a new composite annotationview that first adds your image and then the actual MKAnnotationView:

@implementation MyCustomAnnotationView

- (void) viewDidLoad 
{   
    // First add the image to our subviews
    UIImageView *view = [[UIImageView alloc] initWithImage: myImageProperty];
    [self.view addSubview: view];
    [view release];

    // Then add the MKAnnotationView on top of it
    MKAnnotationView *annotation = [[MKAnnotationView alloc] init]; 
    [self.view addSubview: annotation]; 
    [annotation release];
}                        

@end
MathieuK
Thanks, I'll give that a try.
Adolfo
+1  A: 

Thanks for the input, here's basically what I ended up doing without subclassing:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id )annotation {

    MKAnnotationView *annView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:nil];

    UIImage *image = [UIImage imageNamed:@"image.png"];
    UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
    [annView addSubview:imageView];
    [imageView release];

    MKPinAnnotationView *pinView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:nil];     
    [annView addSubview:pinView];
    [pinView release];

    return annView;
}

I only needed one pin, so I set reuseIdentifier to nil.

Adolfo
How can you hide the pin doing this?
ing0
+1  A: 

I have subclassed the MKAnnotatonView and overrode the initWithAnnotation:resueIdentifier and drawRect methods to add another image behind the "front" image.

It seems that that is what Apple's MKAnnotationView class reference is suggesting us to do.

Only that it is tricky. If you are subclassing the MKAnnotationView, there is still the image property existing. They have done something about the properly so that it is linked with drawing. Perhaps, they have overridden the drawRect to draw the image AFTER the initialization is done.

Also, if you don't set the image property, the frame of your custom annotationView is set to size 0, and the drawRect method does not get called.

Finally, Apple says that the images should be totally filled, i.e. uses a transparent colour for the background of the drawings.

So: In your subclass:

- (id)initWithAnnotation:(id <MKAnnotation>)annotation reuseIdentifier:(NSString *)identifier
{
    self = [super initWithAnnotation:annotation reuseIdentifier:identifier];
    if (self) 
    {       
        UIButton *rightButton = [UIButton buttonWithType: UIButtonTypeDetailDisclosure];
        [rightButton addTarget:self 
                        action:@selector(myShowAnnotationAddress:) 
              forControlEvents:UIControlEventTouchUpInside];
        self.rightCalloutAccessoryView = rightButton;

        self.canShowCallout = YES; 
        self.multipleTouchEnabled = NO;

        self.frame = CGRectMake(0, 0, 65, 100);
        self.backgroundColor = [UIColor clearColor];        

        return self;
    }
    return nil;
}

- (void)drawRect:(CGRect)rect
{
        CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSaveGState(context);

    CGPoint drawPoint = CGPointMake(0.0f, 0.0f);

    UIImage *shadowImage = [UIImage imageNamed:@"shadow_image.png"];
    [shadowImage drawAtPoint:drawPoint];

    UIImage *frontImage = [UIImage imageNamed:@"front_image.png"];
        [frontImage drawAtPoint:drawPoint];

    CGContextRestoreGState(context);
}

After I made the answer, I realize that you actually wanted to draw behind MKPinAnnotationView. My answer is not that, although it shows where the drawing perhaps should be done. Obviously MKPinAnnottions has its own drawing method to present a Pin and its shadow.

I think that probably you can retrieve the Pin image from the self.image property. As to the shadow, I am not certain... It may be using OPEN GL drawing method to add the shadow, or simply combining a shadow image.

Finally, the image comes with animation. I am guessing that that is where the animation is run. At this stage, though, I have not tested.

Yoichi