2

I've successfully implemented the custom map annotation callout code from the asynchrony blog post . (When user taps a map pin, I show a customized image instead of the standard callout view).

The only remaining problem is that the callout occupies the entire width of the view, and the app would look much better if the width corresponded to the image I'm using.

screen shot

I have subclassed MKAnnotationView, and when I set it's contentWidth to the width of the image, the triangle does not always point back to the pin, or the image is not even inside it's wrapper view.Images are wrong

Any help or suggestions would be great. Thanks.

Community
  • 1
  • 1
Rayfleck
  • 12,116
  • 8
  • 48
  • 74

1 Answers1

1

I ran into a similar problem when implementing the CalloutMapAnnotationView for the iPad. Basically I didn't want the iPad version to take the full width of the mapView.

In the prepareFrameSize method set your width:

- (void)prepareFrameSize {
    // ...
    // changing frame x/y origins here does nothing
    frame.size = CGSizeMake(320.0f, height);
    self.frame = frame;
}

Next you'll have to calculate the xOffset based off the parentAnnotationView:

- (void)prepareOffset {
    // Base x calculations from center of parent view
    CGPoint parentOrigin = [self.mapView convertPoint:self.parentAnnotationView.center 
                                             fromView:self.parentAnnotationView.superview];
    CGFloat xOffset =   0;
    CGFloat mapWidth = self.mapView.bounds.size.width;
    CGFloat halfWidth = mapWidth / 2;
    CGFloat x = parentOrigin.x + (320.0f / 2);

    if( parentOrigin.x < halfWidth && x < 0 ) // left half of map
        xOffset = -x;
    else if( parentOrigin.x > halfWidth && x > mapWidth ) // right half of map
        xOffset = -( x - mapWidth);
    // yOffset calculation ...
}

Now in drawRect:(CGRect)rect before the callout bubble is drawn:

- (void)drawRect:(CGRect)rect {
    // ...
    // Calculate the carat lcation in the frame
    if( self.centerOffset.x == 0.0f )
        parentX = 320.0f / 2;
    else if( self.centerOffset.x < 0.0f )
        parentX = (320.0f / 2) + -self.centerOffset.x;
    //...
}

Hope this helps put you on the right track.

TrevorL
  • 495
  • 2
  • 7
  • hey, thanks so much for the code! +1 But i still cant figure out how to get the triangle at the bottom of the callout to point directly to the map, having loads of trouble with that. could you please give me some guidance here or should i open up another question? – stackOverFlew Nov 18 '12 at 06:47
  • https://github.com/kv1/custom_callout_mapAnnotationView here is my attempt, having the most trouble with the adjustMapRegionIfNeeded and naturally prepareOffsetX – stackOverFlew Nov 18 '12 at 10:01
  • just opened up a new question: http://stackoverflow.com/questions/13439526/custom-map-annotations-adding-variable-width-to-callout-original-code-by-async – stackOverFlew Nov 18 '12 at 11:15