Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I change the frame position for a custom MKAnnotationView?

I am trying to make a custom annotation view by subclassing MKAnnotationView and overriding the drawRect method. I want the view to be drawn offset from the annotation's position, somewhat like MKPinAnnotationView does it, so that the point of the pin is at the specified coordinates, rather than the middle of the pin. So I set the frame position and size as shown below. However, it doesn't look like I can affect the position of the frame at all, only the size. The image ends up being drawn centered over the annotation position. Any tips on how to achieve what I want?

MyAnnotationView.h:

@interface MyAnnotationView : MKAnnotationView {

}

MyAnnotationView.m:

- (id)initWithAnnotation:(id <MKAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier {
    if (self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier]) {
        self.canShowCallout = YES;
        self.backgroundColor = [UIColor clearColor];
        // Position the frame so that the bottom of it touches the annotation position 
        self.frame = CGRectMake(0, -16, 32, 32);
    }
    return self;
}

- (void)drawRect:(CGRect)rect {
    [[UIImage imageNamed:@"blue-dot.png"] drawInRect:rect];
}
like image 741
andrei Avatar asked Mar 19 '10 17:03

andrei


3 Answers

I tried using centerOffset and for some reason the image was in the right position when zoomed in, but as you zoomed the map out the image would move away from where it was supposed to be. The fix to this was setting the image frame with the offset. Here's the code I used (You can leave out the callout stuff if you don't have a callout), I used the pins from here)

#pragma mark MKMapViewDelegate
- (MKAnnotationView *)mapView:(MKMapView *)aMapView viewForAnnotation:(id <MKAnnotation>)annotation
{
    if(![annotation isKindOfClass:[MyAnnotation class]]) // Don't mess user location
        return nil;

    MKAnnotationView *annotationView = [aMapView dequeueReusableAnnotationViewWithIdentifier:@"spot"];
    if(!annotationView)
    {
        annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"spot"];
        annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
        [(UIButton *)annotationView.rightCalloutAccessoryView addTarget:self action:@selector(openSpot:) forControlEvents:UIControlEventTouchUpInside];
        annotationView.enabled = YES;
        annotationView.canShowCallout = YES;
        annotationView.centerOffset = CGPointMake(7,-15);
        annotationView.calloutOffset = CGPointMake(-8,0);
    }

    // Setup annotation view
    annotationView.image = [UIImage imageNamed:@"pinYellow.png"]; // Or whatever

    return annotationView;
}

Adjust centerOffset and calloutOffset as needed to suit your image, and desired center point, and callout point.

like image 106
BadPirate Avatar answered Sep 19 '22 18:09

BadPirate


Rather than subclass MKAnnotationView, have you tried using a generic MKAnnotationView and setting the image and centerOffset properties?

like image 45
Tom Avatar answered Sep 23 '22 18:09

Tom


Your UIAnnotationView is always drawn at the same scale, the map's zoom level doesn't matter. That's why centerOffset isn't bound with the zoom level.

annView.centerOffset is what you need. If you see that your pin is not at the good location (for example, the bottom center move a little when you change the zoom level), it's because you didn't set the right centerOffset.

By the way, if you want to set the point of the coordinate at the bottom center of the image, the x coordinate of your centerOffset should be 0.0f, as annotationView center the image by default. So try :

annView.centerOffset = CGPointMake(0, -imageHeight / 2);

Answer from [MKAnnotation image offset with custom pin image

like image 31
VICTORGS3 Avatar answered Sep 21 '22 18:09

VICTORGS3