我正在尝试将注释添加到MKMapView
我创建了一个符合CustomMapPin
协议的类MKAnnotation
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
@interface CustomMapPin : NSObject <MKAnnotation> {
CLLocationCoordinate2D coordinate;
NSString *title;
NSString *subtitle;
}
@property(nonatomic, assign) CLLocationCoordinate2D coordinate;
@property(nonatomic, copy) NSString *title;
@property(nonatomic, copy) NSString *subtitle;
@property(nonatomic, strong) NSString *type; // this is to differentiate between the different annotations on the map
@end
我创建了一个类
CustomMapAnnotationView
,它是MKAnnotationView
的子类。CustomMapAnnotationView.h
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
@interface CustomMapAnnotationView : MKAnnotationView
@property (nonatomic, strong) UIImageView *annotationImage;
@end
CustomMapAnnotationView.m
#import "CustomMapAnnotationView.h"
@implementation CustomMapAnnotationView
-(id) initWithAnnotation:(id<MKAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier];
if (self) {
self.frame = CGRectMake(0, 0, 28, 40);
self.backgroundColor = [UIColor clearColor];
self.annotationImage = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 28, 40)];
self.annotationImage.contentMode = UIViewContentModeScaleAspectFit;
[self addSubview:self.annotationImage];
}
return self;
}
@end
我在
FindMechanicViewController
和CLLocationManagerDelegate
的MKMapViewDelegate
中添加自定义引脚该代码段是:
-(void) viewWillAppear:(BOOL)animated {
[self.locationManager startUpdatingLocation];
self.currentLocation = [self.locationManager location];
// Set the region of the map
MKCoordinateSpan mapViewSpan = MKCoordinateSpanMake(0.01, 0.01);
MKCoordinateRegion mapRegion = MKCoordinateRegionMake(self.currentLocation.coordinate, mapViewSpan);
[self.mapView setRegion:mapRegion];
// Add custom pin showing user location
CustomMapPin *annotation = [[CustomMapPin alloc] init];
annotation.title = @"Current Location";
annotation.coordinate = self.currentLocation.coordinate;
annotation.type = @"user location";
[self.mapView addAnnotation:annotation];
}
和委托方法
-(MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
static NSString *reuseId = @"CustomMapPin";
CustomMapAnnotationView *annotationView = (CustomMapAnnotationView *) [self.mapView dequeueReusableAnnotationViewWithIdentifier:reuseId];
if ([annotation isKindOfClass:[CustomMapPin class]]) {
CustomMapPin *customAnnotation = (CustomMapPin *)annotation;
if ([customAnnotation.type isEqualToString:@"user location"]) {
[annotationView setAnnotation:customAnnotation];
[annotationView setImage:[UIImage imageNamed:@"pin_user"]];
[annotationView setCanShowCallout:YES];
}
}
return annotationView;
}
这不会在地图上显示任何内容。我该如何解决 ?
最佳答案
在viewForAnnotation
中,CustomMapAnnotationView
实际上从未分配+初始化(dequeueReusableAnnotationViewWithIdentifier
不会这样做)。
如果viewForAnnotation
甚至被调用,它必须返回nil
,这意味着地图视图必须在某个地方放置红色大头针(如果未调用委托方法,则地图视图将再次默认为红色销)。记录要在其中添加注释的坐标,然后在此处查看。
更正后的viewForAnnotation
可能看起来像这样:
-(MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
if ([annotation isKindOfClass:[CustomMapPin class]]) {
static NSString *reuseId = @"CustomMapPin";
CustomMapAnnotationView *annotationView = (CustomMapAnnotationView *) [self.mapView dequeueReusableAnnotationViewWithIdentifier:reuseId];
if (!annotationView) {
annotationView = [[CustomMapAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:reuseId];
[annotationView setCanShowCallout:YES];
}
CustomMapPin *customAnnotation = (CustomMapPin *)annotation;
//view's annotation should be set regardless of "type"
[annotationView setAnnotation:customAnnotation];
if ([customAnnotation.type isEqualToString:@"user location"]) {
[annotationView setImage:[UIImage imageNamed:@"pin_user"]];
}
else {
//If it's not a "user location", then set image
//to something else otherwise image will either be nil
//or it will show some other annotation's image...
[annotationView setImage:[UIImage imageNamed:@"pin_other"]];
}
return annotationView;
}
return nil;
}
代码的其他一些问题:
在
viewWillAppear
中,代码在调用startUpdatingLocation
后立即检索位置。不能保证每次都能正常工作,即使它“正常”工作,您很可能也会获得旧的缓存位置。如果它不起作用,则注释将以0,0(大西洋)结尾,否则应用将因坐标无效而崩溃。最好在didUpdateLocations
委托方法中读取位置。在viewWillAppear
中,先呼叫startUpdatingLocation
,然后在didUpdateLocations
中,如果位置的准确性和年龄适合您,请呼叫stopUpdatingLocation
,然后使用该位置(创建并添加注释等)。在
CustomMapAnnotationView
中,创建并添加了annotationImage
对象,但从未设置其image
属性。实际上,annotationImage
从未真正用于任何用途。整个
CustomMapAnnotationView
类对于您的目的都是不必要的。在viewForAnnotation
中,代码正在image
上设置CustomMapAnnotationView
属性(而不是使用annotationImage
)。此image
属性是从MKAnnotationView
继承的。内置的基本MKAnnotationView
类是您执行工作所需的全部。它已经具有image
属性,并会自动为您显示它(您无需创建自己的UIImageView
)。