2


I have a MKMapView with some annotations in it. Now, every time when the region changes I load new annotations. That works fine, but if some annotation is near border of the map view and you tap on it, the annotation info window pops out and the mkmapview region moves a little (so that it can show the window nicely), but the problem is that also the regionDidChangeAnimated is called and it reloads all my annotations and of course hides the info window.
I know you can just tap the annotation once again when it's reloaded but for user it seems broken and also you reload annotations when you don't need to.
Is there any way to check whether the regionDidChangeAnimated was called because of a user action or programatically?
Thanks.

haluzak
  • 1,133
  • 3
  • 17
  • 31

3 Answers3

5

When an annotation near the map view edge is tapped and it moves the map to fit the callout, the sequence of events is:

  1. regionWillChangeAnimated is called
  2. didSelectAnnotationView is called
  3. regionDidChangeAnimated is called

Using two BOOL ivar flags, you can watch for this sequence and prevent the re-loading of annotations in regionDidChangeAnimated.

For example:

-(void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated
{
    regionWillChangeAnimatedCalled = YES;
    regionChangedBecauseAnnotationSelected = NO;
}

-(void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
{
    regionChangedBecauseAnnotationSelected = regionWillChangeAnimatedCalled;
}

-(void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated
{
    if (!regionChangedBecauseAnnotationSelected) //note "!" in front
    {
        //reload (add/remove) annotations here...
    }

    //reset flags...
    regionWillChangeAnimatedCalled = NO;
    regionChangedBecauseAnnotationSelected = NO;
}
  • good idea, i didn't think of checking the didSelectAnnotationView method, I'll try it out thanks! :) – haluzak Nov 13 '11 at 13:45
1

You remove all annotations and add new ones in your regionDidChangeAnimated method? I think a more robust solution is to keep track of all annotations you have added to the map using a dictionary and some unique identifier as key (that will not change, database id etc.) . Then in your regionDidChangeAnimated method you only add actually new ones and maybe also remove annotations outside the region.

Mattias Wadman
  • 11,172
  • 2
  • 42
  • 57
0

You may find that it's a better experience to tie loading your new annotations to a UIGestureRecognizer, so you are only loading the new ones when you know for a fact that the user has scrolled the map manually. This can also prevent reloading when the device is rotated. See Jano's answer at determine if MKMapView was dragged/moved.

Community
  • 1
  • 1
ashack
  • 1,192
  • 11
  • 17