2

マップからピンを削除しようとしています。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オブジェクトに有効なアドレスがあります。ただし、何らかの理由で、ピンをドラッグすると、pinViewはnilになります。何かご意見は?ありがとう!

4

1 に答える 1

0

KVO を介して注釈ビューのselectedプロパティを監視する必要はありません。didSelectAnnotationViewデリゲート メソッドと (あなたの場合はさらに良い) のselectedAnnotationsプロパティがあるためMKMapViewです。

ユーザーがピンを選択した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


ドラッグエンドの問題に関しては、現在のコードはビューの を完全に置き換えていますannotationviewForAnnotationこれは、ビューがデリゲート メソッドで作成または再利用されている場合にのみ良い考えだと思います。drag-end メソッドではview.annotation、完全に新しいオブジェクトに置き換えるのではなく、 のプロパティを更新してみてください。

于 2012-10-05T12:08:00.873 に答える