[英]Custom annotation view is being removed from its superview after setting map view center coordinate
我正在開發一個位置感知應用程序,它使用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實例。 為什么會發生這種情況以及解決方法可能是什么?
進一步調查顯示更奇怪的行為。 我在adjustMapRegionIfNeeded
添加了一堆調試NSLog來打印每個注釋可見性,並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], @"?!");
我遇到了同樣的問題(並且很可能使用了與你相同的教程)。
我將一些NSLog放入CalloutAnnotationView
的didMoveToSuperView
,發現在添加CalloutAnnotationView
,它的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];
...
}
這是非常hacky,是的。 如果您找到更好的解決方案,請發布。 :)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.