簡體   English   中英

設置地圖視圖中心坐標后,將從其超級視圖中刪除自定義注記視圖

[英]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放入CalloutAnnotationViewdidMoveToSuperView ,發現添加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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM