Alex Rivera | Logout

Is it possible to continuously track the MKMapView region while scrolling/zooming?

Asked 2012-05-29T09:02:27.913
8

I'd like to update my UI according to a MKMapView continuously when the user zooms or scrolls around the map. (Not only after the scrolling has ended, that works fine.)

I tried the delegate method mapView:regionWillChangeAnimated: which, according to the documentation, "is called whenever the currently displayed map region changes. During scrolling, this method may be called many times to report updates to the map position." https://developer.apple.com/documentation/mapkit/mkmapviewdelegate

- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated
{
    [self updateUIAcordingToMapViewRegionChange];
}

But unfortunately this doesn't work because the documentation seems not to be telling the truth. The method is only called once at the very beginning of the region change. During scrolling, while the finger is down and moving around, the method is never called again.

The only post about this problem I could find was by macrumors member namanhams: http://forums.macrumors.com/showthread.php?t=1225172 But nobody came up with any ideas...

As a workaround I tried setting up a timer in regionWillChange (and invalidate it in regionDidChange):

- (void)handleRegionChange:(NSTimer*)timer
{
   [self updateUIAcordingToMapViewRegionChange];
} 

- (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated
{
    self.mapRegionIsChangingTimer = [NSTimer scheduledTimerWithTimeInterval:0.1
                                                    target:self
                                                  selector:@selector(handleRegionChange:)
                                                  userInfo:nil
                                                   repeats:YES];
}

                    
                    
                    
Edit
Report

1 Answer

9

This will work:

@interface MapViewController () {
    NSTimer *_updateUITimer;
}

@end

@implementation MapViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    _updateUITimer = [NSTimer timerWithTimeInterval:0.1 
                                             target:self 
                                           selector:@selector(updateUI) 
                                           userInfo:nil 
                                            repeats:YES];

    [[NSRunLoop mainRunLoop] addTimer:_updateUITimer forMode:NSRunLoopCommonModes];

}

- (void)dealloc
{
    [_updateUITimer invalidate];
}

- (void)updateUI
{
    // Update UI
}

@end

Another way is creating timer in mapView:regionWillChangeAnimated and invalidate it in mapView:regionDidChangeAnimated.

answered 2012-10-24T09:08:53.633

Your Answer