【iOS開發-111】自訂圖釘Annotation以及2種導航劃線的方法介紹

來源:互聯網
上載者:User

標籤:

(1)自訂圖釘Annotation的樣式,也就是定義view,主要的方法是如下,傳遞一個圖釘annotation模型,然後返回一個MKAnnotationView,這個MKAnnotationView有一個image屬性,設定這個屬性,就能設定它的樣式了。

-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{}


關鍵提示,這個MKAnnotationView和tableViewCell類似,可以迴圈利用,先從mapView中取,取不到再建立。

主要代碼:

#import "ViewController.h"#import <MapKit/MapKit.h>#import <CoreLocation/CoreLocation.h>#import "WPAnnotation.h"@interface ViewController ()<MKMapViewDelegate>@property (weak, nonatomic) IBOutlet MKMapView *mapView;@property(nonatomic,strong) CLLocationManager *locMgr;@end@implementation ViewController-(CLLocationManager *)locMgr{    if (_locMgr==nil) {        _locMgr=[[CLLocationManager alloc]init];    }    return _locMgr;}- (void)viewDidLoad {    [super viewDidLoad];    if ([[UIDevice currentDevice].systemVersion doubleValue]>=8.0) {        [self.locMgr requestWhenInUseAuthorization];    }    //設定代理    self.mapView.delegate=self;    //添加兩個圖釘    WPAnnotation *anno0=[[WPAnnotation alloc]init];    anno0.coordinate=CLLocationCoordinate2DMake(40, 116);    [email protected]"全聚德";    [email protected]"全北京最好的烤鴨店";    [email protected]"category_1";    [self.mapView addAnnotation:anno0];        WPAnnotation *anno1=[[WPAnnotation alloc]init];    anno1.coordinate=CLLocationCoordinate2DMake(39, 115);    [email protected]"萬達影院";    [email protected]"全中國最頂尖的觀影聖地";    [email protected]"category_5";    [self.mapView addAnnotation:anno1];}-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{    static NSString *[email protected]"annoView";    MKAnnotationView *annoView=[mapView dequeueReusableAnnotationViewWithIdentifier:ID];    if (annoView==nil) {        annoView=[[MKAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:ID];        //點擊圖釘出現資訊(自訂view的圖釘預設點擊不彈出)        annoView.canShowCallout=YES;    }    //再傳遞一次annotation模型(賦值)    annoView.annotation=annotation;        WPAnnotation *anno=annotation;    annoView.image=[UIImage imageNamed:anno.icon];        return annoView;}@end

圖釘模型,多了一個icon屬性,因為我們要自訂圖釘,所以需要圖形屬性:

#import <Foundation/Foundation.h>#import <MapKit/MapKit.h>@interface WPAnnotation : NSObject<MKAnnotation>@property (nonatomic, assign) CLLocationCoordinate2D coordinate;@property (nonatomic, copy) NSString *title;@property (nonatomic, copy) NSString *subtitle;//自訂圖釘圖片@property(nonatomic,copy) NSString *icon;@end

(2)如果我們加入追蹤使用者現有位置時

//追蹤使用者位置self.mapView.userTrackingMode=MKUserTrackingModeFollow;

發現會有如下報錯:[MKUserLocation icon]: unrecognized selector sent to instance 0x7f89baecab50

主要原因是,追蹤使用者位置的MKUserLocation也是一個圖釘(藍色發光的那個圈圈),它也要經過viewForAnnotation這個代理方法返回自訂的圖釘,但是它是沒有icon屬性的,所以報錯。我們應該在viewForAnnotation中添加一個判斷:

//如果是系統內建的圖釘,則返回預設的,否則下面要設定icon時會報錯,因為系統的圖釘沒有icon屬性if (![annotation isKindOfClass:[WPAnnotation class]]) return nil;


(3)還有一個MKPinAnnotationView是MKAnnotationView的子類,屬性多2個,一個是設定顏色,就是可以設定圖釘的顏色,還有一個是設定圖釘從天而降。

- (void)viewDidLoad {    [super viewDidLoad];    ......    [self.mapView addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapMapView:)]];}-(void)tapMapView:(UITapGestureRecognizer *)tap{    //擷取點    CGPoint point=[tap locationInView:tap.view];    //點轉座標    CLLocationCoordinate2D coordi=[self.mapView convertPoint:point toCoordinateFromView:self.mapView];    WPAnnotation *anno=[[WPAnnotation alloc]init];    anno.coordinate=coordi;    [email protected]"全聚德";    [email protected]"來一隻鴨子,老闆!";    [self.mapView addAnnotation:anno];}-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{    static NSString *[email protected]"map";    MKPinAnnotationView *annoView=(MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:ID];    if (annoView==nil) {        annoView=[[MKPinAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:ID];        //設定描述資訊能點擊出現        annoView.canShowCallout=YES;        //設定顏色        annoView.pinColor=MKPinAnnotationColorGreen;        //設定第一次出現從天而降        annoView.animatesDrop=YES;    }    return annoView;}



(4)自訂一個MKAnnotationView,並利用代理方法,監聽圖釘的點擊,點擊後,再彈出一個“圖釘”(只不過這個圖釘是自訂MkAnnotationView的)。

我們一般返回一個圖釘視圖,用下面這個類似於tableViewCell的方法。

-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{    if ([annotation isKindOfClass:[WPDescriptionAnnotation class]]) {        WPAnnotationView *annoView=[WPAnnotationView annotationWithMapView:mapView];        annoView.annotation=annotation;        return annoView;    }else if ([annotation isKindOfClass:[WPAnnotation class]]){        WPTuanGouAnnotationView *annoView=[WPTuanGouAnnotationView annotationWithMapView:mapView];        annoView.annotation=annotation;        return annoView;    }    return nil;}

點擊某一個圖釘視圖,也類似於點擊tableView的某一行(這裡有一些判斷語句十分實用):

//點擊圖釘,彈出一個自訂的圖釘充當描述資訊-(void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view{    if (![view isKindOfClass:[WPTuanGouAnnotationView class]]) return;    //刪除所有再添加,保證只有1個,也防止重複    for (id annotation in mapView.annotations) {        if ([annotation isKindOfClass:[WPDescriptionAnnotation class]]) {            [mapView removeAnnotation:annotation];        }    }    WPAnnotation *anno=view.annotation;    WPDescriptionAnnotation *descAnno=[[WPDescriptionAnnotation alloc]init];    descAnno.tuangou=anno.tuangou;    [mapView addAnnotation:descAnno];}

我們一般在項目中添加圖釘,是有資料模型的。先把這個資料模型賦值給圖釘,然後再添加。當然,圖釘需要在自己的類中設定setTuangou也就是設定資料模型。

for (WPTuanGou *tuan in self.tuangous) {        WPAnnotation *anno=[[WPAnnotation alloc]init];        anno.tuangou=tuan;        [self.mapView addAnnotation:anno];}

我們一般在項目中,都是把模型和圖釘,當做參數在不同的對象之間傳遞。


(5)導航劃線


#import "ViewController.h"#import <CoreLocation/CoreLocation.h>#import <MapKit/MapKit.h>#import "WPAnnotation.h"@interface ViewController ()<MKMapViewDelegate>@property (weak, nonatomic) IBOutlet MKMapView *mapView;@property(nonatomic,strong) CLGeocoder *geocoder;@end@implementation ViewController-(CLGeocoder *)geocoder{    if (_geocoder==nil) {        _geocoder=[[CLGeocoder alloc]init];    }    return _geocoder;}- (void)viewDidLoad {    [super viewDidLoad];    self.mapView.delegate=self;        NSString *[email protected]"廣州";    NSString *[email protected]"北京";    //這個方法只能生效1個,所以不能分開寫    [self.geocoder geocodeAddressString:add1 completionHandler:^(NSArray *placemarks, NSError *error) {        if (error) return;        CLPlacemark *fromPm=[placemarks firstObject];        [self.geocoder geocodeAddressString:add2 completionHandler:^(NSArray *placemarks, NSError *error) {            CLPlacemark *toPm=[placemarks firstObject];            [self addLineFrom:fromPm to:toPm];        }];    }];}-(void)addLineFrom:(CLPlacemark *)fromPm to:(CLPlacemark *)toPm{    //添加2個圖釘    WPAnnotation *anno0=[[WPAnnotation alloc]init];    anno0.coordinate=fromPm.location.coordinate;    [self.mapView addAnnotation:anno0];        WPAnnotation *anno1=[[WPAnnotation alloc]init];    anno1.coordinate=toPm.location.coordinate;    [self.mapView addAnnotation:anno1];        //設定方向請求    MKDirectionsRequest *request=[[MKDirectionsRequest alloc]init];    //設定起點終點    MKPlacemark *sourcePm=[[MKPlacemark alloc]initWithPlacemark:fromPm];    request.source=[[MKMapItem alloc]initWithPlacemark:sourcePm];    MKPlacemark *destiPm=[[MKPlacemark alloc]initWithPlacemark:toPm];    request.destination=[[MKMapItem alloc]initWithPlacemark:destiPm];    //定義方向對象    MKDirections *dirs=[[MKDirections alloc]initWithRequest:request];    //計算路線    [dirs calculateDirectionsWithCompletionHandler:^(MKDirectionsResponse *response, NSError *error) {        NSLog(@"總共有%lu條線路",(unsigned long)response.routes.count);        for (MKRoute *route in response.routes) {            [self.mapView addOverlay:route.polyline];        }    }];}//劃線就是添加路徑,就是添加遮蓋-(MKOverlayRenderer *)mapView:(MKMapView *)mapView rendererForOverlay:(id<MKOverlay>)overlay{    MKPolylineRenderer *renderer=[[MKPolylineRenderer alloc]initWithOverlay:overlay];    renderer.strokeColor=[UIColor redColor];    return renderer;}@end

還有一種方式建立導航,即利用MKMapItem:

    MKMapItem *from=[[MKMapItem alloc]initWithPlacemark:[[MKPlacemark alloc] initWithPlacemark:fromPm]];    MKMapItem *to=[[MKMapItem alloc]initWithPlacemark:[[MKPlacemark alloc] initWithPlacemark:toPm]];    NSMutableDictionary *options=[NSMutableDictionary dictionary];    options[MKLaunchOptionsDirectionsModeKey]=MKLaunchOptionsDirectionsModeDriving;    options[MKLaunchOptionsShowsTrafficKey][email protected];    [MKMapItem openMapsWithItems:@[from,to] launchOptions:options];

【iOS開發-111】自訂圖釘Annotation以及2種導航劃線的方法介紹

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.