【问题标题】:MKMapView viewForAnnotation: returning nilMKMapView viewForAnnotation:返回零
【发布时间】:2012-09-25 02:21:37
【问题描述】:

我正在尝试从地图中删除图钉。我在 MKPinAnnotationView 的 @"selected" 属性上有一个观察者,所以我知道要删除哪个对象。当用户点击垃圾桶图标并选择了一个图钉时,将调用此方法:

- (IBAction)deleteAnnotationView:(id)sender {
    MKPinAnnotationView *pinView = (MKPinAnnotationView *)[self.mapView viewForAnnotation:self.currentAddress];
    [pinView removeObserver:self forKeyPath:@"selected"];

    [self.mapView removeAnnotation:self.currentAddress];
    [self.map removeLocationsObject:self.currentAddress];
}

如果我不将图钉拖到任何地方,这种方法就可以正常工作。如果我拖动图钉,我在上述方法中的 pinView 返回 nil,并且 MKPinAnnotationView 永远不会从 MKMapView 中删除。我不确定为什么。这是 didChangeDragState 委托方法:

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view didChangeDragState:(MKAnnotationViewDragState)newState fromOldState:(MKAnnotationViewDragState)oldState {
    if (newState == MKAnnotationViewDragStateEnding) {
        CLLocationCoordinate2D draggedCoordinate = view.annotation.coordinate;

        CLGeocoder *geocoder = [[CLGeocoder alloc] init];
        CLLocation *location = [[CLLocation alloc] initWithLatitude:draggedCoordinate.latitude longitude:draggedCoordinate.longitude];
        [geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {
            // Check for returned placemarks
            if (placemarks && [placemarks count] > 0) {
                CLPlacemark *topResult = [placemarks objectAtIndex:0];

                AddressAnnotation *anAddress = [AddressAnnotation annotationWithPlacemark:topResult inContext:self.managedObjectContext];
                view.annotation = anAddress;
                self.currentAddress = anAddress;
            }
        }];
    }
}

在 didChangeDragState: 和 deleteAnnotationView: 方法中,我的 self.address 对象都有一个有效地址。但是由于某种原因,当 pin 被拖动时,pinView 为 nil。有什么想法吗?谢谢!

【问题讨论】:

  • 观察 selected 属性应该是不必要的,因为 MKMapView 中有 didSelectAnnotationView 委托方法和 selectedAnnotations 属性。在拖动端,您正在替换视图的注释——不确定这是否正确。您应该尝试更新 view.annotation 的属性,而不是替换为全新的对象。
  • 我不需要一个观察者来知道什么时候没有选择任何 吗?我基本上使用它来启用和禁用垃圾桶按钮。如果在地图上没有选择大头针,我不希望它显示。我想我知道的唯一方法是查看地图上所有图钉的@selected 属性。
  • @Anna Karenina 您的建议是更新当前的 AddressAnnotation 而不是创建一个新的,这起到了作用。你能把它作为答案,这样我就可以结束这个问题了吗?谢谢!

标签: objective-c mkmapview mkpinannotationview


【解决方案1】:

应该没有必要通过 KVO 观察注解视图的 selected 属性,因为 MKMapView 中有 didSelectAnnotationView 委托方法和(在您的情况下更好)selectedAnnotations 属性。

假设用户选择了一个pin后点击了垃圾桶,那么垃圾桶点击方法可以通过selectedAnnotations属性获取当前选中的注解。例如:

if (mapView.selectedAnnotations.count == 0)
{
    //No annotation currently selected
}
else
{
    //The currently selected annotation is the first object in the array...
    id<MKAnnotation> ann = [mapView.selectedAnnotations objectAtIndex:0];

    //do something with ann...
}

在上面的例子中,不需要访问注解的视图,不需要观察者,也不需要你自己的“currentAddress”属性。

如果您想在选择注释时立即执行某些操作,您可以将代码放在didSelectAnnotationView 委托方法中。在那里,选择的注解是view.annotation


关于拖拽端的问题,目前的代码完全替代了视图的annotation。我认为这只是在 viewForAnnotation 委托方法中创建或重用视图时的一个好主意。在拖尾方法中,您应该尝试更新view.annotation 的属性,而不是替换为全新的对象。

【讨论】:

    猜你喜欢
    • 2012-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-23
    • 2016-11-24
    • 2021-10-24
    相关资源
    最近更新 更多