2

私のアプリでは、住所テキストを使用して入力する 2 つの住所 UITextfields があります。私はこの動作が欲しい:

  • ユーザーが住所テキストフィールドを入力するとすぐに、地図が下から表示されます。(すでに行われています)
  • ユーザーは地図で遊んでいます。彼がそれを行うと、今まさにドロップしようとしているフローティング注釈オブジェクトが表示されます。
  • ボタン (mkmapview のサブビュー) を押すと、このフローティング注釈がマップにドロップされます。
  • ユーザーが [完了] ボタンを押すとすぐに、マップ上の注釈の場所が逆ジオコーディングされます。
  • マップ ビューが消えます (既に行われています)。
  • UITextfield には、マップ ビューの中心に対応する住所テキストが入力されます。
  • 別の UITextfield についても同じことが繰り返されます。

これは mkmapview の非常にストレートな使用例だと思います。しかし、これがすでに行われている例は見つかりません。UIKit で明らかな何かが欠けていますか?

助けてくれて本当にありがとうございます....

編集:

Apple の docsを読んだところ、これを指し示す多くの解決策が見つかりました。ただし、それらはすべて MKPinAnnotationView (または MKAnnotationView) がオーバーライドされていると想定しているようです。

それは必要ですか?はいの場合、ドラッグ以外にサブクラスにどれだけ提供する必要がありますか?

4

1 に答える 1

7

サブクラス化する必要はありませんMKPinAnnotationView。ただそれを使用してください。カスタム動作を探している場合にのみ、サブクラス化する必要があります。ただし、viewForAnnotation適切に構成できるように a を記述すると便利です。しかし、通常、標準の構成はMKPinAnnotationView十分に単純であるため、サブクラス化は必要ありません。

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
    if ([annotation isKindOfClass:[MKUserLocation class]])
        return nil;

    MKPinAnnotationView *annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"DroppedPin"];

    annotationView.draggable = YES;
    annotationView.canShowCallout = YES;
    annotationView.animatesDrop = YES;

    return annotationView;
}

そうは言っても、独自の注釈クラスを持つことは珍しくありません。少なくとも 2 つの理由でこれを行う可能性があります。

  1. MKPlacemarkアノテーションのプロパティとしてリバース ジオコーディングを保持する場合があります。論理的には、ジオコーディングされた情報は、ビューではなく注釈のプロパティのように見えます。次に、ドロップされたピンのこのプロパティを照会placemarkして、他のビューに戻す必要がある情報を取得できます。

  2. 必要に応じて、プロパティを逆ジオコード検索するようにアノテーションを構成することもできますが、placemark変更時にタイトルを逆ジオコードされたアドレスに変更することcoordinateもできます。このようにして、ユーザーはマップ上でピンをドラッグ アンド ドロップしているときにリバース ジオコーディングに関するアクティブなフィードバックを取得しますが、コードは依然として非常に単純です。

したがって、次のような注釈クラスがある場合があります。

@interface DroppedAnnotation : NSObject <MKAnnotation>

@property (nonatomic, strong) MKPlacemark *placemark;
@property (nonatomic) CLLocationCoordinate2D coordinate;
@property (nonatomic, strong) NSString *title;
@property (nonatomic, strong) NSString *subtitle;

@end

@implementation DroppedAnnotation

- (void)setCoordinate:(CLLocationCoordinate2D)coordinate
{
    CLLocation *location = [[CLLocation alloc] initWithLatitude:coordinate.latitude
                                                      longitude:coordinate.longitude];
    CLGeocoder *geocoder = [[CLGeocoder alloc] init];
    [geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) {
        // do whatever you want here ... I'm just grabbing the first placemark

        if ([placemarks count] > 0 && error == nil)
        {
            self.placemark = placemarks[0];

            NSArray *formattedAddressLines = self.placemark.addressDictionary[@"FormattedAddressLines"];
            self.title = [formattedAddressLines componentsJoinedByString:@", "];
        }
    }];

    _coordinate = coordinate;
}

@end

そして、View Controller はこの新しいクラスを使用できます。

@property (nonatomic, weak) id<MKAnnotation> droppedAnnotation;

- (void)dropPin
{
    // if we've already dropped a pin, remove it

    if (self.droppedAnnotation)
        [self.mapView removeAnnotation:self.droppedAnnotation];

    // create new dropped pin

    DroppedAnnotation *annotation = [[DroppedAnnotation alloc] init];
    annotation.coordinate = self.mapView.centerCoordinate;
    annotation.title = @"Dropped pin"; // initialize the title
    [self.mapView addAnnotation:annotation];

    self.droppedAnnotation = annotation;
}

明確にするために、独自の注釈クラスは必要ありません。MKPointAnnotationたとえば、標準を使用できます。ただし、View Controller は呼び出しを維持し、逆ジオコーディングされた情報自体を追跡する必要があります。カスタム注釈クラスを使用すると、コードが少しすっきりして論理的になると思います。

于 2013-03-16T16:00:17.433 に答える