iphone - iOS - 如何使用 mkmapview 作为位置选择器

标签 iphone ios mkmapview mkannotation

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

  • 只要用户输入地址文本字段, map 就会从下方出现。 (已经完成)
  • 用户玩 map 。当他这样做时,出现了一个即将掉落的 float 注释对象。
  • 按下按钮(mkmapview 的 subview )时,会将此 float 注释放到 map 上。
  • 只要用户按下“完成”按钮, map 上的注释位置就会进行反向地理编码。
  • map View 消失(已经完成)。
  • UITextfield 填充了与 map View 中心对应的地址文本。
  • 对另一个 UITextfield 重复相同的操作。

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

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

编辑:

我读了Apple's docs ,我发现很多solutions指向这一点。 然而,它们似乎都假设 MKPinAnnotationView(或 MKAnnotationView)被覆盖。

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

最佳答案

无需子类化 MKPinAnnotationView .就用它吧。如果您正在寻找一些自定义行为,您只应该将它子类化。但是写一个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作为注释的属性。从逻辑上讲,地理编码信息似乎是注释的属性,而不是 View 的属性。然后可以查询这个placemark放置的图钉的属性,以获取您需要传递回其他 View 的任何信息。

  2. 如果需要,您可以将注释配置为同时执行反向地理编码查找,这将 placemark属性,还可以在更改其 coordinate 时将标题更改为反向地理编码地址, 也。通过这种方式,用户在将图钉拖放到 map 上时可以获得有关反向地理编码的积极反馈,但代码仍然非常简单:

因此,您可能有一个注释类:

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

关于iphone - iOS - 如何使用 mkmapview 作为位置选择器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15448998/

相关文章:

iphone - 从 sqlite 数据库中查找列中的最大值

ios - 旋转后键盘延伸高度不正确

ios - swift 3 : Understand syntax change for UITableViewDataSource method

ios - 如何从 iOS 中的 map 针获取位置

ios - CGFloat 地板到 NSInteger

iphone - 如何使用 Objective C 在两台机器之间创建远程连接

ios - 将图层属性从 UIView 覆盖到子类 UIView

ios - Realm iOS : Cannot Convert value of type 'Dogs.Type' to expected argument type 'T.Type'

ios - MKAnnotation 点击​​时没有响应

ios - IOS中Storyboard中如何添加GMSMapView