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];
}
But that doesn't work, too. All method calls from the timer are executed all at once just after the scrolling has ended. Seems like scrolling the mapView is blocking the main thread or something…
I also read this post on stackoverflow, but unfortunately didn't completely understand it: Monitor MKMapView redraw events So if the solution to my problem lies indeed in that SO-thread, please tell me so, and I try to dig into it's details.
I still hope I'm simply too stupid or too blind to find the correct delegate method, and really appreciate any hints, workarounds and best practices to deal with MKMapView region tracking.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With