带有自定义 MKAnnotation 的 MKMapView

发布于 2024-10-17 22:26:31 字数 130 浏览 8 评论 0原文

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

它们是一些餐馆的地方。我该怎么做呢?

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

谢谢,伙计们。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

执笔绘流年 2024-10-24 22:26:31

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

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

  • MKAnnotation
  • MKAnnotationView

对于最基本的 MKAnnotation,您只需采用协议并为标题和副标题返回 nil,但您也可以在注释中携带更多信息以进行扩展标注点击附件指示器后。例如,您可以使用 viewDidLoad 中的 addAnnotation: 将所有注释添加到 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。根据苹果公司的说法,默认情况下你不应该进行大量标注。他们推荐使用标准尺寸的标注,并有一个按钮可以打开更大的标注。他们在蓝色圆圈图标中使用小写 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 的 WeatherAnnotationView 示例 说明了重写drawRect。

First, let's define custom as meaning not simply title and subtitle. We want to change the size of the MKAnnotation and include some custom graphics.

There are two parts to an annotation you might want to customize:

  • MKAnnotation
  • MKAnnotationView

For the most basic MKAnnotation you would simply adopt the protocol and return nil for title and subtitle, but you could also carry a lot more information in your annotation for an extended callout upon tapping an accessory indicator. You can add all of the annotations to the MKMapView using addAnnotation: in viewDidLoad for example.

MKAnnotation Header

@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

@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

The next step is to customize the callout from the pin dropped. To do this you need to customize MKAnnotationView. According to Apple you shouldn't make a huge callout by default. They recommend a standard size callout that has a button to open a bigger one. They use the lowercase i in a blue circle icon. Those icons can be set via the view's leftCalloutAccessoryView and rightCalloutAccessoryView property. If you already adopted the MKMapViewDelegate protocol and set yourself as the MKMapView's delegate you will get the callback for viewForAnnotation:.

MKAnnotationView MKMapViewDelegate callback

- (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;
}

You can further customize this in a custom view overriding the drawRect method, providing an image to the image property, or you could even implement an MKAnnotationView in a XIB. It is worth some experimentation.

Apple's WeatherAnnotationView Example illustrates overriding drawRect.

醉梦枕江山 2024-10-24 22:26:31

我有一个案例,我想要一个标准 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];

I had a case where I wanted something like a standard Pin annotation, but the designer wanted a custom graphic.

I wrote a subclass of MKAnnotationView to display the graphic. The only difference is that it overrides the standard class's 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

Then in the class that displays the map, I made the class implement the MKMapViewDelegate protocol. The mapView:viewForAnnotation: method creates a new instance of BlipAnnotationView if necessary.

- (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;
}

Finally I set the class as the delegate of the map view in awakeFromNib:

- (void)awakeFromNib
{
    [...]
    [_theMapView setDelegate:self];
}

I didn't have to change the code that positioned the annotation at all:

MKPointAnnotation *annotationPoint = [[MKPointAnnotation alloc] init];
[annotationPoint setCoordinate:[userLocation coordinate]];
[annotationPoint setTitle:label];
[_theMapView addAnnotation:annotationPoint];
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文