2011-08-22 70 views
31

我需要在所有其他註釋之上繪製當前用戶註釋(藍點)。現在它在我的其他註釋下被繪製並隱藏起來。我想調整這個註解視圖的Z-index(藍點)並將它帶到最高點,有誰知道如何?iOS MapKit用戶位置註釋的Z索引

更新: 所以我現在可以得到一個MKUserLocationView的句柄,但我該如何把它轉發?

- (void) mapView:(MKMapView *)aMapView didAddAnnotationViews:(NSArray *)views { 
    for (MKAnnotationView *view in views) { 
     if ([[view annotation] isKindOfClass:[MKUserLocation class]]) { 
      // How do I bring this view to the front of all other annotations? 
      // [???? bringSubviewToFront:????]; 
     } 
    } 
} 

回答

34

感謝Paul Tiarks的幫助,終於使用下面列出的代碼工作。我遇到的問題是MKUserLocation註釋先於其他註釋被添加到地圖中,所以當您添加其他註釋時,它們的順序看起來是隨機的,並且仍然會在MKUserLocation註釋之上結束。爲了解決這個問題,我必須將所有其他註釋移動到後面,並將MKUserLocation註釋移動到前面。

- (void) mapView:(MKMapView *)aMapView didAddAnnotationViews:(NSArray *)views 
{ 
    for (MKAnnotationView *view in views) 
    { 
     if ([[view annotation] isKindOfClass:[MKUserLocation class]]) 
     { 
      [[view superview] bringSubviewToFront:view]; 
     } 
     else 
     { 
      [[view superview] sendSubviewToBack:view]; 
     } 
    } 
} 

更新:您可能需要添加下面的代碼,以確保其滾動時從地圖的可視區域的藍點繪製在上面。

- (void)mapView:(MKMapView *)mapView regionDidChangeAnimated:(BOOL)animated 
{   
    for (NSObject *annotation in [mapView annotations]) 
    { 
    if ([annotation isKindOfClass:[MKUserLocation class]]) 
    { 
     NSLog(@"Bring blue location dot to front"); 
     MKAnnotationView *view = [mapView viewForAnnotation:(MKUserLocation *)annotation]; 
     [[view superview] bringSubviewToFront:view]; 
    } 
    } 
} 
+0

這個解決方案對我來說似乎並不可靠。如果我拖動地圖使其偏離屏幕並返回到地圖,藍色地點點就會在我的自定義註釋下面結束,大概是因爲地圖視圖會用原始佈局重新繪製視圖。 –

+1

@DanJ然後使用' - (void)mapView:(MKMapView *)mapView regionWillChangeAnimated:(BOOL)animated'中的相同邏輯並通過mapView.annotations循環並找到'[mapView viewForAnnotation:annotation]' – jmcopeland

+1

好點,解決問題,儘管我發現將regionDidChangeAnimated中的代碼放在比regionWillChangeAnimated更可靠的代碼中。我會更新您的答案以包含額外的代碼。 FTR,當使用大量註釋時,會有輕微的性能問題,因爲ChangeAnimated方法應儘可能輕量化。 –

2

嘗試,讓用戶位置註釋(也許在mapView: didAddAnnotationViews:)的引用,然後把該視圖的MapView前面所有的註釋已被添加之後。

+0

我還沒有想出得到它的一個把手,因爲你可以」噸測試它的類MKUserLocationView和我的所有其他註釋是普通的MKAnnotationView對象和MKUserLocationView是MKAnnotationView的子類...我正在考慮將我的註釋切換到覆蓋,以便我可以管理這些的zindex並保持它們分開來自用戶位置註釋。任何其他想法? – jmcopeland

+1

您應該能夠測試註解屬性的類以查看它是否爲MKUserLocation並將其作爲用戶位置視圖保留。 –

+0

感謝上面的你的建議,我已經能夠獲得MKUserLocationView的位置,但是我沒有能夠把它推進。我用bringSubviewToFront嘗試過各種咒語:但我沒有嘗試過。有什麼想法嗎? – jmcopeland

0

這是一種使用謂詞的方法。我覺得應該是更快

NSPredicate *userLocationPredicate = [NSPredicate predicateWithFormat:@"class == %@", [MKUserLocation class]]; 
NSArray* userLocation = [[self.mapView annotations] filteredArrayUsingPredicate:userLocationPredicate]; 

if([userLocation count]) { 
    NSLog(@"Bring blue location dot to front"); 
    MKAnnotationView *view = [self.mapView viewForAnnotation:(MKUserLocation *)[userLocation objectAtIndex:0]]; 
    [[view superview] bringSubviewToFront:view]; 
} 
25

另一種解決方案: 設置註釋視圖層的z位置(annotationView.layer.zPosition)中:

- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views;

+0

這個解決方案對我來說是最可靠的。 –

+0

這比管理子視圖的順序要容易得多。 –

+3

這使得來自其他針腳的封面標註 – yuf

0

使用Underscore.m

_.array(mapView.annotations). 
    filter(^ BOOL (id<MKAnnotation> annotation) { return [annotation 
isKindOfClass:[MKUserLocation class]]; }) 
    .each(^ (id<MKAnnotation> annotation) { [[[mapView 
viewForAnnotation:annotation] superview] bringSubviewToFront:[mapView 
viewForAnnotation:annotation]]; }); 
9

官方答案到那個線程是錯誤的...使用zPosition確實是使用regionDidChan最好的方法和最快的geAnimated ...

否則,您會遭受地圖上許多註釋帶來的巨大性能影響(因爲每次更改幀都會重新掃描所有註釋)。並已測試它...

所以當創建註釋的視圖(或在didAddAnnotationViews)設置: self.layer.zPosition = -1; (下面的所有其他)

並且如yuf指出: 這使得銷罩標註從其他引腳 - yuf 12月5日'13 20:25

即註解視圖下方會出現其他引腳。

修復,只需reput z位置爲0,有選擇

-(void) mapView:(MKMapView*)mapView didSelectAnnotationView:(MKAnnotationView*)view { 
    if ([view isKindOfClass:[MyCustomAnnotationView class]]) 
     view.layer.zPosition = 0; 
    ... 
} 

-(void) mapView:(MKMapView*)mapView didDeselectAnnotationView:(MKAnnotationView*)view { 
    if ([view isKindOfClass:[MyCustomAnnotationView class]]) 
     view.layer.zPosition = -1; 
    ... 
} 
+0

當你只需要管理視覺效果時,這種解決方案非常好,但是如果你也需要處理點擊/觸摸的優先級,它就不起作用了(你點擊一個看起來在別人之上的針(因爲zPosition是0),但實際上你點擊下面的一個引腳)。 – jptsetung

+0

這是蘋果的標準pin行爲...更改zlocation並不妨礙這...但這是另一個問題。爲了不彈出,你應該在自定義註釋中使用self.canShowCallout = NO – altagir

1

斯威夫特,當你3:

internal func mapView(_ mapView: MKMapView, didAdd views: [MKAnnotationView]) { 
     for annotationView in views { 
      if annotationView.annotation is MKUserLocation { 
       annotationView.bringSubview(toFront: view) 
       return 
      } 
      annotationView.sendSubview(toBack: view) 
     } 
}