滚动/缩放时是否可以连续跟踪MKMapView区域?

时间:2012-05-29 09:02:28

标签: ios mkmapview mapkit

当用户在地图上缩放或滚动时,我想连续更新我的UI。 (不仅在滚动结束后,工作正常。)

我尝试了委托方法mapView:regionWillChangeAnimated:根据文档,“只要当前显示的地图区域发生变化就会调用。在滚动期间,可以多次调用此方法来报告地图位置的更新。” https://developer.apple.com/documentation/mapkit/mkmapviewdelegate

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

但不幸的是,这不起作用,因为文件似乎没有说实话。该方法仅在区域变化的最开始时调用一次。在滚动期间,当手指向下并四处移动时,永远不会再次调用该方法。

我能找到的关于这个问题的唯一帖子是由macrumors成员namanhams: http://forums.macrumors.com/showthread.php?t=1225172 但没有人想出任何想法......

作为一种解决方法,我尝试在regionWillChange中设置一个计时器(并在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];
}

但这也行不通。来自计时器的所有方法调用都在滚动结束后立即执行。看起来像滚动mapView阻止了主线程或什么......

我也在stackoverflow上阅读了这篇文章,但遗憾的是并没有完全理解它: Monitor MKMapView redraw events 因此,如果我的问题的解决方案确实存在于那个SO线程中,请告诉我,我试着深入了解它的细节。

我仍然希望我过于愚蠢或太盲目无法找到正确的委托方法,并且非常感谢处理MKMapView区域跟踪的任何提示,解决方法和最佳实践。

1 个答案:

答案 0 :(得分:9)

这将有效:

@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

另一种方法是在mapView中创建计时器:regionWillChangeAnimated并在mapView中使其无效:regionDidChangeAnimated。