2011-07-28 109 views
3

我正在使用MKMapView和使用MKAnnotationView子類實現的自定義標註泡泡的位置感知應用程序。昨天我遇到了一個微妙的錯誤,當自定義註釋視圖不顯示。調查這個問題有點後,我想出了以下結果:設置地圖視圖中心座標後,自定義註釋視圖正從其超級視圖中移除

  • 這個問題表現只有當我試圖用捏手勢縮放後立即顯示自定義註解視圖。因此,例如,如果你捏,然後平移地圖視圖一切工作正常。以編程方式更改地圖縮放不會導致這個問題出現在didMoveToSuperview無論是
  • 設置斷點在我的自定義註解視圖類揭示了以下回溯:

    #0 -[CalloutMapAnnotationView didMoveToSuperview] 
    #1 0x00186857 in -[UIView(Hierarchy) removeFromSuperview]() 
    #2 0x00e14c70 in -[MKAnnotationContainerView _removeAnnotationView:updateCollections:]() 
    #3 0x00e196cb in -[MKAnnotationContainerView _removeAnnotationViews:]() 
    #4 0x00e19f51 in -[MKAnnotationContainerView _displayAnnotationsInMapRect:includePending:animated:removeOffscreenAnnotations:]() 
    #5 0x00e1aaa7 in -[MKAnnotationContainerView _refreshDisplayedAnnotations]() 
    #6 0x00dfc508 in -[MKMapView _didChangeRegionMidstream:centerPoint:]() 
    #7 0x00e0165c in -[MKMapView _goToCenterCoordinate:zoomLevel:animationType:]() 
    #8 0x00df34c3 in -[MKMapView goToCenterCoordinate:zoomLevel:animationType:]() 
    #9 0x00e0086f in -[MKMapView setCenterCoordinate:animated:]() 
    #10 0x00036fc3 in -[CalloutMapAnnotationView adjustMapRegionIfNeeded] 
    #11 0x00037c63 in -[CalloutMapAnnotationView didMoveToSuperview] 
    #12 0x0017f750 in -[UIView(Internal) _addSubview:positioned:relativeTo:]() 
    #13 0x0017dc00 in -[UIView(Hierarchy) insertSubview:atIndex:]() 
    #14 0x00e2049f in -[MKAnnotationContainerView _addViewForAnnotation:]() 
    #15 0x00e199a5 in -[MKAnnotationContainerView _addViewsForAnnotations:animated:]() 
    #16 0x00e19f0d in -[MKAnnotationContainerView _displayAnnotationsInMapRect:includePending:animated:removeOffscreenAnnotations:]() 
    #17 0x00e1a9e2 in -[MKAnnotationContainerView showAddedAnnotationsAnimated:]() 
    

這裏,CalloutMapAnnotationView是我的自定義標註視圖類。 adjustMapRegionIfNeeded如果註釋過於接近映射邊界,則該方法會調整地圖視圖的中心座標,從而導致從其超級視圖中刪除CalloutMapAnnotationView實例。爲什麼會發生這種情況以及可能的解決方法?

進一步調查顯示更奇怪的行爲。我加了一堆調試NSLogs的adjustMapRegionIfNeeded打印每個註釋的知名度和想出了以下結果:

(顯示自定義註解)正常情況下:不顯示

Custom callout annotation location: (55.821350, 37.497490) 
Parent annotation location: (55.821350, 37.497490) 
Custom callout annotation visibility before adjustment: 1 
Custom callout annotation visibility after adjustment: 1 
Parent annotation visibility: 1 

自定義註釋:

Custom callout annotation location: (55.821350, 37.497490) 
Parent annotation location: (55.821350, 37.497490) 
Custom callout annotation visibility before adjustment: 1 
Custom callout annotation visibility after adjustment: 0 
Parent annotation visibility: 1 

儘管父註釋和具有相同位置的自定義調出註釋,其中一人是可見的得到控制而另一個不是。我測試註釋能見度下面的代碼:

[[self.mapView annotationsInMapRect:self.mapView.visibleMapRect] containsObject:self.annotation] 

更重要的,下面的斷言失敗

MKMapRect visibleMapRect = self.mapView.visibleMapRect; 
MKMapPoint annotationPoint = MKMapPointForCoordinate(self.annotation.coordinate); 
NSAssert(MKMapRectContainsPoint(visibleMapRect, annotationPoint) == [[self.mapView annotationsInMapRect:visibleMapRect] containsObject:self.annotation], @"?!"); 

回答

1

我遇到了同樣的問題(和最有可能使用的你做的相同的教程)。

我已經把一些NSLogs到CalloutAnnotationViewdidMoveToSuperView,發現加入CalloutAnnotationView,它的父的MKAnnotationContainerView一個實例,被釋放。這可能意味着MKMapView在放大或縮小時內部重新創建其MKAnnotationContainerView

我所做的就是做一些檢查一點點加入之後:

[self.mapView addAnnotation: m_calloutAnnotation]; 
[self performSelector: @selector(checkCalloutAnnotationVisibility) 
      withObject: nil 
      afterDelay: 0.15]; 
... 

- (void) checkCalloutAnnotationVisibility 
{ 
    if (!m_calloutAnnotationView.window) 
    { 
    [self.mapView removeAnnotation: m_calloutAnnotation]; 
    [self.mapView addAnnotation: m_calloutAnnotation]; 

    [self performSelector: @selector(checkCalloutAnnotationVisibility) 
       withObject: nil 
       afterDelay: 0.1]; 
    } 
} 

... 

- (void)   mapView: (MKMapView *)  mapView 
didDeselectAnnotationView: (MKAnnotationView *) view 
{ 
    [NSObject cancelPreviousPerformRequestsWithTarget: self 
              selector: 
            @selector(checkCalloutAnnotationVisibility) 
              object: nil]; 
    ... 
} 

這是非常哈克,是的。如果您找到更好的解決方案,請發帖。 :)

+1

嗯,我設法解決這個問題,通過移動區域調整代碼到'mapView:didAddAnnotationViews:'這似乎爲我解決了一些問題。 –

+0

現在這是解決它的更優雅的方式。尼斯。現在擺脫快速修復... –

相關問題