3

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.

4

2 回答 2

14

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

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

  • MKAnnotation
  • MKAnnotationView

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

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 方法的自定义视图中进一步自定义它,为图像属性提供图像,或者您甚至可以在 XIB 中实现 MKAnnotationView。值得进行一些实验。

Apple 的 WeatherAnnotationView 示例说明了覆盖 drawRect。

于 2012-07-07T09:49:28.940 回答
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];
于 2012-09-26T00:15:31.213 回答