iOS 高德地圖(五)繪製點標記

(一)添加默認樣式點標記

  • iOS SDK提供的大頭針標註MAPinAnnotationView,通過它可以設置大頭針顏色、是否顯示動畫、是否支持長按後拖拽大頭針改變座標等。
    **
  • **這裏用到的類是
    MAPinAnnotationView
    讓我們對它的屬性有個瞭解。
    **
  • 繼承關係圖:

    2016-09-30_18-07-06.png

  • 屬性圖:
    2016-09-30_17-49-14.png

iOS SDK提供的大頭針標註MAPinAnnotationView,通過它可以設置大頭針顏色、是否顯示動畫、是否支持長按後拖拽大頭針改變座標等。在地圖上添加大頭針標註的步驟如下:

(1) 修改ViewController.m文件,在viewDidAppear方法中添加如下所示代碼添加標註數據對象。

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    MAPointAnnotation *pointAnnotation = [[MAPointAnnotation alloc] init];
    pointAnnotation.coordinate = CLLocationCoordinate2DMake(39.989631, 116.481018);
    pointAnnotation.title = @"方恆國際";
    pointAnnotation.subtitle = @"阜通東大街6號";

    [_mapView addAnnotation:pointAnnotation];
}

(2) 實現 協議中的 mapView:viewForAnnotation:回調函數,設置標註樣式。如下所示:


- (MAAnnotationView *)mapView:(MAMapView *)mapView viewForAnnotation:(id <MAAnnotation>)annotation
{
    if ([annotation isKindOfClass:[MAPointAnnotation class]])
    {
        static NSString *pointReuseIndentifier = @"pointReuseIndentifier";
        MAPinAnnotationView*annotationView = (MAPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:pointReuseIndentifier];
        if (annotationView == nil)
        {
            annotationView = [[MAPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:pointReuseIndentifier];
        }
        annotationView.canShowCallout= YES;       //設置氣泡可以彈出,默認爲NO
        annotationView.animatesDrop = YES;        //設置標註動畫顯示,默認爲NO
        annotationView.draggable = YES;        //設置標註可以拖動,默認爲NO
        annotationView.pinColor = MAPinAnnotationColorPurple;
        return annotationView;
    }
    return nil;
}

(二)自定義標註圖標

  • 若大頭針樣式的標註不能滿足您的需求,您可以自定義標註圖標
    其實就是修改一下MAAnnotationView 的 image 屬性
    步驟:

**(1) 添加標註數據對象,可參考大頭針標註的步驟(1)。
(2) 導入標記圖片文件到工程中。這裏我們導入一個名爲 restauant.png 的圖片文件。
(3) 在 協議的回調函數mapView:viewForAnnotation:中修改 MAAnnotationView 對應的標註圖片。示例代碼如下:**

- (MAAnnotationView *)mapView:(MAMapView *)mapView viewForAnnotation:(id<MAAnnotation>)annotation
{
    if ([annotation isKindOfClass:[MAPointAnnotation class]])
    {
        static NSString *reuseIndetifier = @"annotationReuseIndetifier";
        MAAnnotationView *annotationView = (MAAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:reuseIndetifier];
        if (annotationView == nil)
        {
            annotationView = [[MAAnnotationView alloc] initWithAnnotation:annotation
reuseIdentifier:reuseIndetifier];
        }
        annotationView.image = [UIImage imageNamed:@"restaurant"];
        //設置中心點偏移,使得標註底部中間點成爲經緯度對應點
        annotationView.centerOffset = CGPointMake(0, -18);
        return annotationView;
    }
    return nil;
}

2016-09-30_18-13-54.png

(三)添加自定義氣泡

  • 氣泡在iOS中又稱爲callout,它由背景和氣泡內容構成,如下圖所示:
    2016-09-30_18-15-21.png

思路:
我們點擊標註可以彈出氣泡
是利用了MAAnnotationView 的這個方法


- (void) setSelected:animated:

我們需要重寫這個方法,選中時新建並添加氣泡視圖,傳入數據;非選中時刪除氣泡視圖。
**
1.自定義一個氣泡視圖
2.定義MAAnnotationView 的子類,重寫 setSelected:animated: 方法
3.修改ViewController.m,在MAMapViewDelegate的回調方法mapView:viewForAnnotation中的修改annotationView的類型
**

1.每個氣泡顯示的內容是根據您的需求定義的,這裏我們按照如上圖所示的氣泡介紹實現一個自定義氣泡的步驟:

(1) 新建自定義氣泡類 CustomCalloutView,繼承 UIView。

(2) 在 CustomCalloutView.h 中定義數據屬性,包含:圖片、商戶名和商戶地址。

@interface CustomCalloutView : UIView

@property (nonatomic, strong) UIImage *image; //商戶圖
@property (nonatomic, copy) NSString *title; //商戶名
@property (nonatomic, copy) NSString *subtitle; //地址

@end

(3) 在CustomCalloutView.m中重寫UIView的drawRect方法,繪製彈出氣泡的背景。

#define kArrorHeight        10

- (void)drawRect:(CGRect)rect
{

    [self drawInContext:UIGraphicsGetCurrentContext()];

    self.layer.shadowColor = [[UIColor blackColor] CGColor];
    self.layer.shadowOpacity = 1.0;
    self.layer.shadowOffset = CGSizeMake(0.0f, 0.0f);

}

- (void)drawInContext:(CGContextRef)context
{

    CGContextSetLineWidth(context, 2.0);
    CGContextSetFillColorWithColor(context, [UIColor colorWithRed:0.3 green:0.3 blue:0.3 alpha:0.8].CGColor);

    [self getDrawPath:context];
    CGContextFillPath(context);

}

- (void)getDrawPath:(CGContextRef)context
{
    CGRect rrect = self.bounds;
    CGFloat radius = 6.0;
    CGFloat minx = CGRectGetMinX(rrect),
    midx = CGRectGetMidX(rrect),
    maxx = CGRectGetMaxX(rrect);
    CGFloat miny = CGRectGetMinY(rrect),
    maxy = CGRectGetMaxY(rrect)-kArrorHeight;

    CGContextMoveToPoint(context, midx+kArrorHeight, maxy);
    CGContextAddLineToPoint(context,midx, maxy+kArrorHeight);
    CGContextAddLineToPoint(context,midx-kArrorHeight, maxy);

    CGContextAddArcToPoint(context, minx, maxy, minx, miny, radius);
    CGContextAddArcToPoint(context, minx, minx, maxx, miny, radius);
    CGContextAddArcToPoint(context, maxx, miny, maxx, maxx, radius);
    CGContextAddArcToPoint(context, maxx, maxy, midx, maxy, radius);
    CGContextClosePath(context);
}

(4) 定義用於顯示氣泡內容的控件,並添加到SubView中。

如上圖所示氣泡,我們需要一個UIImageView和兩個UILabel,添加方法如下:

#define kPortraitMargin     5
#define kPortraitWidth      70
#define kPortraitHeight     50

#define kTitleWidth         120
#define kTitleHeight        20

@interface CustomCalloutView ()

@property (nonatomic, strong) UIImageView *portraitView;
@property (nonatomic, strong) UILabel *subtitleLabel;
@property (nonatomic, strong) UILabel *titleLabel;

@end

@implementation CustomCalloutView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self)
    {
        self.backgroundColor = [UIColor clearColor];
        [self initSubViews];
    }
    return self;
}

- (void)initSubViews
{
    // 添加圖片,即商戶圖
    self.portraitView = [[UIImageView alloc] initWithFrame:CGRectMake(kPortraitMargin, kPortraitMargin, kPortraitWidth, kPortraitHeight)];

    self.portraitView.backgroundColor = [UIColor blackColor];
    [self addSubview:self.portraitView];

    // 添加標題,即商戶名
    self.titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(kPortraitMargin * 2 + kPortraitWidth, kPortraitMargin, kTitleWidth, kTitleHeight)];
    self.titleLabel.font = [UIFont boldSystemFontOfSize:14];
    self.titleLabel.textColor = [UIColor whiteColor];
    self.titleLabel.text = @"titletitletitletitle";
    [self addSubview:self.titleLabel];

    // 添加副標題,即商戶地址
    self.subtitleLabel = [[UILabel alloc] initWithFrame:CGRectMake(kPortraitMargin * 2 + kPortraitWidth, kPortraitMargin * 2 + kTitleHeight, kTitleWidth, kTitleHeight)];
    self.subtitleLabel.font = [UIFont systemFontOfSize:12];
    self.subtitleLabel.textColor = [UIColor lightGrayColor];
    self.subtitleLabel.text = @"subtitleLabelsubtitleLabelsubtitleLabel";
    [self addSubview:self.subtitleLabel];
}
(5) 在CustomCalloutView.m中給控件傳入數據。


- (void)setTitle:(NSString *)title
{
    self.titleLabel.text = title;
}

- (void)setSubtitle:(NSString *)subtitle
{
    self.subtitleLabel.text = subtitle;
}

- (void)setImage:(UIImage *)image
{
    self.portraitView.image = image;
}

2.自定義AnnotationView,步驟如下:

(1) 新建類CustomAnnotationView,繼承MAAnnotationView或MAPinAnnotationView。若繼承MAAnnotationView,則需要設置標註圖標;若繼承MAPinAnnotationView,使用默認的大頭針標註

(2) 在CustomAnnotationView.h中定義自定義氣泡屬性,代碼如下所示:

#import "CustomCalloutView.h"

@interface CustomAnnotationView : MAAnnotationView

@property (nonatomic, readonly) CustomCalloutView *calloutView;

@end

(3) 在CustomAnnotationView.m中修改calloutView屬性,如下:

@interface CustomAnnotationView ()

@property (nonatomic, strong, readwrite) CustomCalloutView *calloutView;

@end

(4) 重寫選中方法setSelected。選中時新建並添加calloutView,傳入數據;非選中時刪除calloutView。

#define kCalloutWidth       200.0
#define kCalloutHeight      70.0

- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
    if (self.selected == selected)
    {
        return;
    }

    if (selected)
    {
        if (self.calloutView == nil)
        {
            self.calloutView = [[CustomCalloutView alloc] initWithFrame:CGRectMake(0, 0, kCalloutWidth, kCalloutHeight)];
            self.calloutView.center = CGPointMake(CGRectGetWidth(self.bounds) / 2.f + self.calloutOffset.x,
                                                  -CGRectGetHeight(self.calloutView.bounds) / 2.f + self.calloutOffset.y);
        }

        self.calloutView.image = [UIImage imageNamed:@"building"];
        self.calloutView.title = self.annotation.title;
        self.calloutView.subtitle = self.annotation.subtitle;

        [self addSubview:self.calloutView];
    }
    else
    {
        [self.calloutView removeFromSuperview];
    }

    [super setSelected:selected animated:animated];
}

注意:提前導入building.png圖片。
**
3.修改ViewController.m
**
在MAMapViewDelegate的回調方法mapView:viewForAnnotation中的修改annotationView的類型,代碼如下:

#import “CustomAnnotationView.h”

- (MAAnnotationView *)mapView:(MAMapView *)mapView viewForAnnotation:(id<MAAnnotation>)annotation
{
    if ([annotation isKindOfClass:[MAPointAnnotation class]])
    {
        static NSString *reuseIndetifier = @"annotationReuseIndetifier";
        CustomAnnotationView *annotationView = (CustomAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:reuseIndetifier];
        if (annotationView == nil)
        {
            annotationView = [[CustomAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:reuseIndetifier];
        }
        annotationView.image = [UIImage imageNamed:@"restaurant"];

        // 設置爲NO,用以調用自定義的calloutView
        annotationView.canShowCallout = NO;

        // 設置中心點偏移,使得標註底部中間點成爲經緯度對應點
        annotationView.centerOffset = CGPointMake(0, -18);
        return annotationView;
    }
    return nil;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章