How to change frame position for custom MKAnnotationView?

I am trying to do a custom annotation view by subclassing MKAnnotationView and overriding the drawRect method. I want the view to be offset from the position of the annotation, which is somewhat similar to MKPinAnnotationView , so that the output point is in the given coordinates, and not in the middle of the pin. Therefore, I set the position and size of the frame as shown below. However, this is not like I can affect the position of the frame in general, only the size. The image ends by centering on 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]; } 
+6
iphone mapkit mkannotation
source share
4 answers

Instead of subclassing MKAnnotationView, you tried to use a common MKAnnotationView and set the image and centerOffset ?

+15
source share

I tried using centerOffset, and for some reason, the image was in the correct position when zoomed in, but as you zoomed in, the image would be removed from where it should have been. Fix it - setting the frame of the image with an offset Here is the code I used (you can leave the callouts outside if you don't have the callout), I used the contacts 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; } 

Configure centerOffset and calloutOffset as needed according to your image, desired center point, and offset point.

+19
source share

Your UIAnnotationView always drawn at the same scale, the zoom level of the map does not matter. Therefore, centerOffset not related to the zoom level.

annView.centerOffset is what you need. If you see that your contact is not in a good place (for example, the lower center moves a little when the zoom level changes), this is because you did not set the correct centerOffset .

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

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

From [ MKAnnotation image offset with custom pin image

+2
source share

Thanks for the BadPirate example.

I tried using UIImageview, but I don't think it is necessary.

My class looked like this

 @interface ImageAnnotationView : MKAnnotationView { UIImageView *_imageView; id m_parent; BusinessMapAnnotation *m_annotation; NSString *stitle; } 

And implementation

 - (id)initWithAnnotation:(id <MKAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier { self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier]; self.frame = CGRectMake(0, 0, kWidth, kHeight); self.backgroundColor = [UIColor clearColor]; self.m_annotation = (BusinessMapAnnotation*)annotation; NSString* categoryTitle = m_annotation.sCTitle; NSString* l_titleString = @"NearPin.png"; if (categoryTitle!= nil ) { if ([categoryTitle length] > 0) { //NSLog(@"%@", categoryTitle); l_titleString = [NSString stringWithFormat:@"Map%@.png", categoryTitle]; //NSLog(@"%@", l_titleString); } } self.stitle = m_annotation.sTitle; _imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:([stitle isEqualToString:@"You are here"]) ? @"Pushpin_large.png":l_titleString]]; _imageView.contentMode = UIViewContentModeCenter; _imageView.frame = CGRectMake(kBorder, kBorder, kWidth, kHeight); [self addSubview:_imageView]; _imageView.center = ([stitle isEqualToString:@"You are here"]) ? CGPointMake(15.0, -10.0):CGPointMake(kWidth/2, 0.0); return self; } 
-3
source share

All Articles