带有自定义MKAnnotation的MKMapView

时间:2011-02-15 18:23:07

标签: ios mkmapview mkannotation

我有一个MKMapView。 我想在我的地图上放置一个自定义的MKAnnotation。

他们是一些餐馆的地方。我该怎么办?

我的问题是如何制作自定义MKAnnotation?

谢谢,伙计们。

3 个答案:

答案 0 :(得分:14)

首先,让我们将自定义定义为不仅仅是标题和副标题。我们想要更改MKAnnotation的大小并包含一些自定义图形。

您可能想要自定义注释的两个部分:

  • MKAnnotation
  • MKAnnotationView

对于最基本的MKAnnotation,你只需采用协议并为标题和副标题返回nil,但是你也可以在你的注释中携带更多信息,以便在点击辅助指示符时扩展标注。您可以使用addAnnotation将所有注释添加到MKMapView:例如,在viewDidLoad中。

MKAnnotation标题

@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

MKAnnotation实施

@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 MKMapViewDelegate回调

- (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方法,为image属性提供图像,或者甚至可以在XIB中实现MKAnnotationView。值得一些实验。

Apple's WeatherAnnotationView Example说明了覆盖drawRect。

答案 1 :(得分:5)

我有一个案例,我想要一些标准的Pin注释,但设计师想要一个自定义图形。

我写了一个MKAnnotationView的子类来显示图形。唯一的区别是它会覆盖标准类的image

BlipAnnotationView.h

#import <MapKit/MapKit.h>

@interface BlipAnnotationView : MKAnnotationView

- (id)initWithAnnotation:(id<MKAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier;

@end

BlipAnnotationView.m

#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];

答案 2 :(得分:1)

如果您完全想要自定义注释的标注视图.. 看到这个链接.. http://blog.asolutions.com/2010/09/building-custom-map-annotation-callouts-part-1/