2

在我的应用程序中,我有两个要使用地址文本填充的地址 UITextfields。我想要这种行为:

  • 一旦用户输入地址文本字段,就会从下方出现一个地图。(已经完成了)
  • 用户玩地图。当他这样做时,会出现一个即将掉落的浮动注释对象。
  • 按下按钮(mkmapview 的子视图)时,会将这个浮动注释放到地图上。
  • 一旦用户按下完成按钮,地图上的注释位置就会被反向地理编码。
  • 地图视图消失(已经完成)。
  • UITextfield 填充了与地图视图中心相对应的地址文本。
  • 另一个 UITextfield 也是如此。

我相信这是 mkmapview 的一个非常直接的用例。但是找不到任何已经完成的例子。我在 UIKit 中遗漏了一些非常明显的东西吗?

非常感谢您的帮助....

编辑:

我阅读了Apple 的文档,发现了许多指向这一点的解决方案。然而,他们似乎都假设 MKPinAnnotationView(或 MKAnnotationView)被覆盖。

有必要吗?如果是,除了拖动之外,我需要在子类中提供多少?

4

1 回答 1

7

无需子类化MKPinAnnotationView。就用它吧。如果您正在寻找一些自定义行为,您应该只将它作为子类。但是编写 a 很有用,viewForAnnotation因此您可以正确配置它。但通常我发现标准的配置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;
}

话虽如此,拥有自己的注释类并不罕见。我这样做可能至少有两个原因:

  1. 您可以将反向地理编码保留MKPlacemark为注释的属性。从逻辑上讲,地理编码信息似乎是注释的属性,而不是视图的属性。然后,您可以查询placemark放置的 pin 的此属性,以获取您需要传递回其他视图的任何信息。

  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

你的视图控制器可以使用这个新类:

@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。但是你的视图控制器必须保持调用并跟踪反向地理编码信息本身。我只是认为当您使用自定义注释类时,代码会更清晰,更合乎逻辑。

于 2013-03-16T16:00:17.433 回答