Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I tell when regionChange event on MKMapView is programatic or user-drag of MKMapView?

I have an MKMapView with a registered delegate so I can listen for region change events (specifically, regionDidChangeAnimated). I'm looking for a robust way of telling if a region change event was the result of a user dragging the map or from a programatic setRegion: request.

My goal is to have an app that auto-centers the map based on a location trace, unless the user has panned the map by hand, at which point auto-centering will turn off. Thus, I'm calling setRegion: to recenter the map view as appropriate, but I have a hard time telling if the resulting regionDidChangeAnimated: call to the delegate is programatic or from a user-pan. I've tried hacking something together, but I keep running into race conditions when the user starts panning just as a location update comes in.

like image 805
Brian Ferris Avatar asked Jun 10 '10 01:06

Brian Ferris


1 Answers

I fixed this problem with a boolean that keeps track of code triggered region/center changes. Not the most elegant solution, but it works like a charm. It is a shame UIMapView does not derive from UIScrollView.

init:

regionChangeFromCode = FALSE;

button action:

-(IBAction) butCenterPressed:(id)sender
{   
    butCenter.selected = !butCenter.selected;       
    if(butCenter.selected)  
        [self setCenter];
}

set center:

-(void) setCenter
{
    regionChangeFromCode = TRUE; //before setCenterCoordinate, otherwise this is FALSE in regionWillChangeAnimated
    [theMap setCenterCoordinate:[self calcCenter]]; //this could also be [theMap setRegion]. Works the same
}

and the map delegate:

- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated
{
    if(!regionChangeFromCode) //so a user did it
    {
        if(butCenter.selected)
            butCenter.selected = FALSE;
    }
    regionChangeFromCode = FALSE;
}

In addition to this I have an update loop that updates the location and calls setCenter. When the button is selected the map center follows, and otherwise the center is left alone.

like image 178
RickyA Avatar answered Oct 29 '22 09:10

RickyA