处理大量的MKMapView注释

Ale*_*lex 10 iphone objective-c mkmapview

我有一个带有大量注释(3000+)的地图视图,当用户缩放到合理的水平时,一切都很好而且快速.

虽然当用户缩小并且大量注释进入视图时,由于一次显示大量注释,因此存在大量减速.处理这个问题的最佳方法是什么?

我正在使用的当前解决方案:

- (void)mapView:(MKMapView *)_mapView regionDidChangeAnimated:(BOOL)animated {

    NSArray *annotations = [_mapView annotations];  
    MapAnnotation *annotation = nil; 

    for (int i=0; i<[annotations count]; i++)
    {
        annotation = (MapAnnotation*)[annotations objectAtIndex:i];
        if (_mapView.region.span.latitudeDelta > .010)
        {
            [[_mapView viewForAnnotation:annotation] setHidden:YES];
            warningLabel.hidden = NO;
        }
        else {
            [[_mapView viewForAnnotation:annotation] setHidden:NO];
            warningLabel.hidden = YES;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

虽然由于环路的大小很大,但在放大和缩小以及滚动时会导致很多速度变慢.我似乎无法想到一个更好的方法来处理这个问题,有没有办法只循环当前正在显示的注释或沿着那些线的东西来减少循环的大小?

Dan*_* T. 7

据我了解您的代码,如果mapView缩小超过某个指定值,您将隐藏所有注释的视图.

在我看来,更像以下的东西会更好:

- (void)mapView: (MKMapView*)_mapView regionDidChangeAnimated: (BOOL)animated
{
    if (_mapView.region.span.latitudeDelta > .010 && self.mapViewsHidden == NO) {
        for (MapAnnotation* annotation in _mapView.annotations) {
            [[_mapView viewForAnnotation: annotation] setHidden: YES];
        }
        [self.warningLabel setHidden: NO];
        [self setMapViewsHidden: YES];
    }
    else if (_mapView.region.span.latitudeDelta <= .010 && self.mapViewsHidden == YES) {
        for (MapAnnotation* annotation in _mapView.annotations) {
            [[_mapView viewForAnnotation: annotation] setHidden: NO];
        }
        [self.warningLabel setHidden: YES];
        [self setMapViewsHidden: NO];
    }
}
Run Code Online (Sandbox Code Playgroud)

有了上述内容,在大多数情况下,这段代码唯一能做的就是检查.

另一种解决方案是在不应该在地图上显示时删除注释.就个人而言,我认为这会更好,这样代码就不必为尚未在地图上显示的注释创建视图.


don*_*kim 6

我会建议一些事情.一,看看方法annotationsInMapRect:.根据文档,它说:

此方法提供了一种快速检索地图特定部分中的注释对象的方法.此方法比自己在注释属性中对对象进行线性搜索要快得多.

二,看看dequeueReusableAnnotationViewWithIdentifier:.根据文档再说,它说:

出于性能原因,通常应该在地图视图中重用MKAnnotationView对象.当注释视图在屏幕外移动时,地图视图会将它们移动到内部管理的重用队列.随着新注释在屏幕上移动,并且提示您的代码提供相应的注释视图,您应始终尝试在创建新视图之前使其出列.在执行滚动等性能关键操作期间,出列可节省时间和内存.

最后,有几点想法.不是每次- (void)mapView:(MKMapView *)_mapView regionDidChangeAnimated:(BOOL)animated调用方法时都进行这些更改,而是根据其他规则执行此操作(例如在计时器被触发后[确保每次调用时都重置计时器])?另一件需要考虑的事情是:如何将注释分组在一起,彼此超级接近?假设您已经缩小到罗德岛看起来超小的地方,可能只有十几个像素宽,而您在罗德岛有100个点 - 您应该只显示一个引脚.

希望这可以帮助!