Ios MapView检测滚动

Ios MapView检测滚动,ios,uiview,mapkit,Ios,Uiview,Mapkit,我希望MKMapView继承自UIScrollView,就像UITableView和UICollectionView一样。通过这种方式,您可以覆盖UIScrollView委托方法并执行需要执行的操作 我发现了将平移手势附加到MapView的方法,如下所示: UIPanGestureRecognizer* mapPanGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(ma

我希望
MKMapView
继承自
UIScrollView
,就像
UITableView
UICollectionView
一样。通过这种方式,您可以覆盖
UIScrollView
委托方法并执行需要执行的操作

我发现了将平移手势附加到
MapView
的方法,如下所示:

UIPanGestureRecognizer* mapPanGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(mapPanGestureHandler:)];
[mapPanGestureRecognizer setDelegate:self];
[self.mapView addGestureRecognizer:mapPanGestureRecognizer];
除了
mapView
中有减速元素之外,这项功能运行得相当好。例如,如果您在中间滚动并抬起手指,地图将继续运行并减速,然后最终停止

我所做的是使用核心图形在我的地图(另一个
UIView
)顶部的覆盖中渲染一些屏幕外注释。除了减速问题,它工作得很好

我只需要知道地图已经移动了。我需要的参数可以直接从地图本身查询

有没有人找到一种在减速时获得回调的技术?我的意思是,我想当手势结束时,我可以使用计时器重复发射半秒左右

协议定义了
mapView:RegiondChangeAnimated:
,当地图显示的区域更改时,将调用该协议。当地图滚动时,它会被反复调用-

讨论只要当前显示的地图 区域变化。在滚动期间,可能会多次调用此方法 报告地图位置的更新。因此,您的实现 此方法的属性应尽可能轻,以避免影响 滚动性能


您应该能够使用此方法访问新地图区域并重新绘制覆盖图(或者如果重新绘制非常耗时,您可以在另一个线程上分派任务来重新绘制覆盖图)

MKMapView
没有类似的委托回调到
UIScrollView
,因此您需要临时修改

有没有人找到一种在减速时获得回调的技术?我的意思是,我想当手势结束时,我可以使用计时器重复发射半秒左右

如果您想准确地使视图与地图的移动保持同步,最好使用
CADisplayLink
,因为每次屏幕刷新后都会收到一个回调。另一方面,如果使用计时器,回调不一定与刷新率一致,您可能会看到工件

您可以这样设置:

CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateViewsBasedOnMapRegion:)];
[link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
- (void)updateViewsBasedOnMapRegion:(CADisplayLink *)link
{
    // update whatever it is you need to update
}
然后按如下方式处理回调:

CADisplayLink *link = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateViewsBasedOnMapRegion:)];
[link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
- (void)updateViewsBasedOnMapRegion:(CADisplayLink *)link
{
    // update whatever it is you need to update
}

您可以专门使用此选项并放弃手势识别器,或者保留手势识别器并在不需要时暂停链接。

Swift中,您只需使用以下代码即可。滚动后,将调用以下重写的方法。您还可以使用
CLLocationCoordinate2DMake
检测滚动量,如下图所示

extension UIViewController: MKMapViewDelegate {
    func mapView(_ mapView: MKMapView, regionDidChangeAnimated animated: Bool) { 
       let coordinate = CLLocationCoordinate2DMake(mapView.region.center.latitude, mapView.region.center.longitude) 
    }
}

您需要知道地图在移动时正在移动,还是仅当它停止移动时才移动?在移动时,是否有手指触摸它。
regiondChangeAnimated
仅偶尔被调用。例如,如果在整个屏幕上平移,它可能只被调用一次或两次。从这个问题上,我推测他正在寻找更频繁的更新。然后,也许结合手势识别器的当前方法和代理方法,手势识别器将捕获当前的大部分动作,并且减速后最终更新的代理Timothy是正确的。这种方法很少被调用。我知道我的测试只有在减速停止时才会调用它。它的姐妹方法“willChange”也只调用一次。我正在寻找能够在对象移动时在地图上流畅地渲染对象的调用。您不能只使用MKAnnotationView并将覆盖渲染到其中吗?如果您使用MKAnnotations,您可以这样做,但在我的例子中,我在地图上使用UICollectionView覆盖作为屏幕外标注位置的指南。自从这篇文章发表以来,很多时间已经过去了,否则我会给出更多的细节。我迫不及待地想明天早上试一试。我同意计时器解决方案是hokey,但正如你所说。。。即兴创作我想在MapView.region属性上使用KVO。但我不确定地图实际更新其区域变量的频率。两种我都试试。谢谢你帮我解决了这个问题。我用本文中的代码替换了平移手势和它的目标选择器。它工作完美,减速和所有。