MKMapView regionDidChangeAnimated called by user action or program

雨燕双飞 提交于 2019-12-07 21:13:52

问题



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.


回答1:


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;
}



回答2:


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.




回答3:


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.



来源:https://stackoverflow.com/questions/8076555/mkmapview-regiondidchangeanimated-called-by-user-action-or-program

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!