【问题标题】:MKMapView with custom MKAnnotation带有自定义 MKAnnotation 的 MKMapView
【发布时间】:2011-02-15 18:23:07
【问题描述】:

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

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

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

谢谢各位。

【问题讨论】:

    标签: ios mkmapview mkannotation


    【解决方案1】:

    首先,让我们将自定义定义为不仅仅是标题和副标题。我们想改变 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's WeatherAnnotationView Example 说明了覆盖 drawRect。

    【讨论】:

      【解决方案2】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-02-15
        • 2013-07-20
        • 1970-01-01
        • 2011-11-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多