8

当用户缩放或滚动地图时,我想根据 MKMapView 不断更新我的 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 阻塞了主线程什么的……</p>

我也在 stackoverflow 上阅读了这篇文章,但不幸的是并没有完全理解它: Monitor MKMapView redraw events 所以如果我的问题的解决方案确实在于那个 SO 线程,请告诉我,我会尝试深入研究它的细节。

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

4

1 回答 1

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 中使其无效。

于 2012-10-24T09:08:53.633 回答