MKAnnotationView frame size won't update MapView until zoom

ios, mkannotation, mkannotationview, objective-c

Solution

I've managed to get things working. I'm pretty sure I've not found the perfect way to do this, but it fitted my needs and in the end didn't affected the User Experience.

I found that the frame was actually been added to the view, but as I've stetted the `frame origin` to be at `0,0` the view was been added outside of the zoom position I was checking.

After noticing that I've noticed that I was able to change the `frame` to the right spot where I wanted the custom bubble to be. But as I zoomed in or out, the `frame` relocated to a different position. Turns out that the `centerOffset` property was doing that, so I had to match the `frame` and the `centerOffset` properties to get them referring to the exact same point on screen and the results were pretty satisfactory. User experience is fluid.

Here's the code for get that working, under the subclass of `MKAnnotationView` that I've created:

- (void)setSelected:(BOOL)selected animated:(BOOL)animated{
[super setSelected:selected animated:animated];

if (selected) {

    //here's the trick: setting the frame to a new position and with different size.
    //as the bubble view is added here and matching that point in view with the
    //centerOffset position. The result looks doesn't affect user experience.
    CGRect frame;
    frame = self.frame;
    frame.size = CGSizeMake(170, 66);
    frame.origin = CGPointMake((self.frame.origin.x)-16.5,(self.frame.origin.y)-49);
    self.frame = frame;
    self.centerOffset = CGPointMake(61, -24.5);

    //remove the pin image from the view as the bubble view will be added
    self.image = nil;

    [self createBubble];
    [self animateIn];
    [self addSubview:bubbleView];

}else {

    [bubbleView removeFromSuperview];

    //reset the center offset and the frame for the AnnotationView to reinsert the pin image
    self.centerOffset = CGPointMake(0, 0);
    CGRect frame;
    frame = self.frame;
    //this is the size of my pins image
    frame.size = CGSizeMake(14, 17);
    frame.origin = CGPointMake((self.frame.origin.x)+16.5 ,(self.frame.origin.y)+49);
    self.frame = frame;

    //discover whats the point view image (I have different pin colors here)
    UIImage *pointImage = [[UIImage alloc] init];

    if ([flagStyle isEqualToString:@"friends"]) {

        pointImage = [UIImage imageNamed:@"point_f.png"];

    }else if([flagStyle isEqualToString:@"world"]){

        pointImage = [UIImage imageNamed:@"point_w.png"];        

    }else if([flagStyle isEqualToString:@"my"]){

        pointImage = [UIImage imageNamed:@"point_m.png"];        

    }


    self.image = pointImage;


}

}

I've been looking for a solution for creating a custom MKAnnotationView with a callout bubble that has a button inside but I was not able to find anything that suited my needs all over internet. This solution works. It's not the perfect implementation but does the job. I hope to help someone with this.

Problem

I'm trying to implement a custom MKAnnotationView with a custom button inside. I don't want to use the callout property of the MKAnnotation because the frame for that view can't be accessed. Instead I used the MKAnnotationView view to add my UIView with my custom callout bubble inside. Everything works fine, even the touch is captured by the button. The only problem is in resizing the MKAnnotationView frame. I'm able to do that during the: `(void)setSelected:(BOOL)selected animated:(BOOL)animated` method inside my custom MKAnnotationView that subclasses MKAnnotationView, but when the resized view should display at MapView, that's only achieved by zooming in or out the map. I've tried passing things such as`needsLayout` and `needsDisplay` but with no success. What am I doing wrong? What's the method that the MapView calls when zooming in and out, so I can call it to refresh the custom MKAnnotationView frame? Here's some code from the CustomMKAnnotationView class that I've created: ``` - (void)setSelected:(BOOL)selected animated:(BOOL)animated{ [super setSelected:selected animated:animated]; if (selected) { self.frame = CGRectMake(0, 0, 170, 66); self.backgroundColor = [UIColor lightTextColor]; self.centerOffset = CGPointMake(54.5, -33); self.image = nil; [self createBubble]; [self animateIn]; [self addSubview:bubbleView]; }else{ [bubbleView removeFromSuperview]; self.frame = CGRectMake(0, 0, 13, 17); self.centerOffset = CGPointMake(0, 0); } } ```

Original source