I've a MKMapView. I want to put a custom MKAnnotation on my map.
They are some restaurant places. How can I do it?
My question is how can I make a custom MKAnnotation?
Thanks, guys.
I've a MKMapView. I want to put a custom MKAnnotation on my map.
They are some restaurant places. How can I do it?
My question is how can I make a custom MKAnnotation?
Thanks, guys.
首先,让我们将自定义定义为不仅仅是标题和副标题。我们想改变 MKAnnotation 的大小并包含一些自定义图形。
您可能想要自定义的注释有两个部分:
对于最基本的 MKAnnotation,您只需采用协议并为标题和副标题返回 nil,但您也可以在注释中携带更多信息,以便在点击附件指示器时进行扩展标注。例如,您可以使用 addAnnotation: 在 viewDidLoad 中将所有注释添加到 MKMapView。
@interface CPAnnotation : NSObject <MKAnnotation> {
@private
CLLocationCoordinate2D _coordinate;
NSString *_title;
NSString *_subtitle;
}
@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
@property (nonatomic, readonly, copy) NSString *title;
@property (nonatomic, readonly, copy) NSString *subtitle;
- (id)initWithCoordinate:(CLLocationCoordinate2D)coordinate;
@end
@implementation CPAnnotation
@synthesize coordinate = _coordinate;
@synthesize title = _title;
@synthesize subtitle = _subtitle;
- (id)initWithCoordinate:(CLLocationCoordinate2D)coordinate {
self = [super init];
if (self != nil) {
self.coordinate = coordinate;
}
return self;
}
- (NSString *)title {
return _title;
}
- (NSString *)subtitle {
return _subtitle;
}
@end
下一步是从丢弃的图钉自定义标注。为此,您需要自定义 MKAnnotationView。根据 Apple 的说法,默认情况下您不应该进行大量标注。他们推荐一个标准尺寸的标注,有一个按钮可以打开一个更大的标注。他们在蓝色圆圈图标中使用小写 i。这些图标可以通过视图的 leftCalloutAccessoryView 和 rightCalloutAccessoryView 属性来设置。如果您已经采用了 MKMapViewDelegate 协议并将自己设置为 MKMapView 的委托,您将获得 viewForAnnotation: 的回调。
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
static NSString *const kAnnotationReuseIdentifier = @"CPAnnotationView";
MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:kAnnotationReuseIdentifier];
if (annotationView == nil) {
annotationView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:kAnnotationReuseIdentifier] autorelease];
annotationView.enabled = YES;
annotationView.canShowCallout = YES;
annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeInfoLight];
}
return annotationView;
}
您可以在覆盖 drawRect 方法的自定义视图中进一步自定义它,为图像属性提供图像,或者您甚至可以在 XIB 中实现 MKAnnotationView。值得进行一些实验。
Apple 的 WeatherAnnotationView 示例说明了覆盖 drawRect。
我有一个案例,我想要一个标准的 Pin 注释,但设计师想要一个自定义图形。
我写了一个子类MKAnnotationView
来显示图形。唯一的区别是它覆盖了标准类的image
.
#import <MapKit/MapKit.h>
@interface BlipAnnotationView : MKAnnotationView
- (id)initWithAnnotation:(id<MKAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier;
@end
#import "BlipAnnotationView.h"
@implementation BlipAnnotationView
- (id)initWithAnnotation:(id<MKAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier];
if (self) {
UIImage *blipImage = [UIImage imageNamed:@"blip.png"];
CGRect frame = [self frame];
frame.size = [blipImage size];
[self setFrame:frame];
[self setCenterOffset:CGPointMake(0.0, -7.0)];
[self setImage:blipImage];
}
return self;
}
@end
然后在显示地图的类中,我让该类实现了MKMapViewDelegate
协议。如果需要,该mapView:viewForAnnotation:
方法会创建一个新的实例。BlipAnnotationView
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
NSLog(@"mapView:%@ viewForAnnotation:%@", mapView, annotation);
static NSString *const kAnnotationIdentifier = @"BlipMapAnnotation";
BlipAnnotationView *annotationView = (BlipAnnotationView *)
[mapView dequeueReusableAnnotationViewWithIdentifier:kAnnotationIdentifier];
if (! annotationView) {
annotationView = [[BlipAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:kAnnotationIdentifier];
}
[annotationView setAnnotation:annotation];
return annotationView;
}
最后,我将类设置为地图视图的代表awakeFromNib
:
- (void)awakeFromNib
{
[...]
[_theMapView setDelegate:self];
}
我根本不必更改定位注释的代码:
MKPointAnnotation *annotationPoint = [[MKPointAnnotation alloc] init];
[annotationPoint setCoordinate:[userLocation coordinate]];
[annotationPoint setTitle:label];
[_theMapView addAnnotation:annotationPoint];