无需子类化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;
}
话虽如此,拥有自己的注释类并不罕见。我这样做可能至少有两个原因:
您可以将反向地理编码保留MKPlacemark
为注释的属性。从逻辑上讲,地理编码信息似乎是注释的属性,而不是视图的属性。然后,您可以查询placemark
放置的 pin 的此属性,以获取您需要传递回其他视图的任何信息。
如果需要,您可以将注释配置为既执行反向地理编码查找,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
。但是你的视图控制器必须保持调用并跟踪反向地理编码信息本身。我只是认为当您使用自定义注释类时,代码会更清晰,更合乎逻辑。