2011-01-23 48 views
10

當用戶放大到合理的水平時,我有一個包含大量註釋(3000+)的地圖視圖,一切都很好,很快。處理大量的MKMapView註解

雖然當用戶縮小和大量的註釋進入視野時,由於一次顯示大量註釋,導致大量減速。處理這個問題的最好方法是什麼?

目前的解決辦法,我使用:

- (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; 
     } 
    } 
} 

偉大的作品雖然由於循環的龐大規模放大和縮小的時候和周圍滾動這會導致大量的放緩。我似乎無法想出一個更好的方法來處理這個問題,有沒有辦法只循環當前顯示的註釋或沿着這些行來減少循環的大小?

回答

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]; 
    } 
} 

通過以上,在大多數情況下,這個代碼做的唯一事情是一對夫婦,如果檢查。

另一種解決方案是在註釋不應顯示在地圖上時刪除註釋。就我個人而言,我認爲這會更好,這樣代碼就不必爲未在地圖上顯示的註釋創建視圖。

6

我會建議一些事情。一,看看方法annotationsInMapRect:。根據文檔,它說:

此方法提供了一種快速方法來檢索地圖的特定部分中的註釋對象。此方法比自己在註釋屬性中進行線性搜索要快得多。

二,看看dequeueReusableAnnotationViewWithIdentifier:。根據文檔再次,它說:

由於性能的原因,你應該通常在你的地圖視圖重用MKAnnotationView對象。隨着註釋視圖移出屏幕,地圖視圖將它們移動到內部管理的重用隊列中。隨着新註釋在屏幕上移動,並且提示您的代碼提供相應的註釋視圖,您應該始終嘗試在創建新視圖之前將現有視圖出列。出隊在諸如滾動之類的關鍵性能操作期間節省時間和內存。

最後,有一些想法。而不是在每次調用- (void)mapView:(MKMapView *)_mapView regionDidChangeAnimated:(BOOL)animated方法時都做這些更改,而是根據其他規則來做這些更改(比如在計時器被觸發後(確保在每次調用此計時器時重置計時器))?另一件需要考慮的事情是:如何將註釋分組在一起,這些註釋彼此超級接近?假設你縮小到羅德島看起來超級小的地方,也許只有十幾個像素寬,你在羅得島有100個點 - 你應該只顯示一個針。

希望這會有所幫助!

+0

嘿donkim,我已經有dequeueReusableAnnotationViewWithIdentifier:到位,但我會研究其他技術,你建議嘗試讓所有的工作更快。這是一個恥辱annotationsInMapRect僅支持> 4.2,似乎它會解決我所有的麻煩 – Alex 2011-01-24 10:34:43

+0

在我的經驗dequeueReusableAnnotationViewWithIdentifier永遠不會返回一箇舊的註釋。 – malhal 2012-06-29 02:14:09

+0

annotationsInMapRect確實比自己計算座標的速度快。 – Skoua 2015-06-28 13:55:52

2

我最終使用OCMapView將羣組中的註釋分組。它的免費,很容易實現到現有的代碼。

它縮小時會自動將您的註釋分組,並且在放大時它們顯示爲非聚簇,因爲它們應該如此。

我知道這是一個古老的問題,但對於其他嘗試做同樣事情的人來說,它是一個很好的選擇。