2013年3月3日 星期日

iOS-MapProgramming(Annotation)

最近小小個趕工了一下Ubike的App,總算有點小成果惹XD,也對地圖有點認識,來記錄一下
(題外話:意外發現powerpoint是強大的繪圖軟體)

Annotation:
首先先來筆記在地圖上如何插針,之前修課的時候一直不太瞭解為什麼同時要實作delegate
看著助教的程式這樣打,我也跟著這樣打(弱爆惹),然後就完成了那次作業QQ
現在終於有新的體悟惹(iOS還真是博大精深,整個程式寫下來都在學design pattern)

1. 首先先不管MKMapViewDelegate的部分,按照以下的步驟可以先實做出簡單地插針
a. 先打實作一個Annotation的class(此Annotation的class需要成為MKAnnotation的delegate)
b. 到mapView的controller裡面把要插針的地方打上[_mapView addAnnotation:annotation]
基本上,上面的步驟應該不難,可是我竟然弄了好久QQ(完全深陷delegate的回圈當中)
2. 實作的部分:
a. 首先先add new file到project資料夾,並選擇objective的格式(加入新的class都這樣加)
在這裡要加撰寫自定的Annotation,再加入後的.h檔顯示如下

#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>

@interface UBStationAnnotation : NSObject <MKAnnotation>
    
@property (nonatomic) CLLocationCoordinate2D coordinate;

//自定的屬性
@property (nonatomic) NSString *stationName;
@property (nonatomic) NSInteger numberOfBike;
@property (nonatomic) NSInteger numberOfSpace;

- (id)initWithTitle: (NSString*)setTitle AndSubTitle:(NSString *)setSubtitle;
@end
b. 完成.h檔之後就完成一半惹,在這裡要筆記一下<MKAnnotation>是什麼
<MKAnnotation>查了一下官方的文件才有點瞭解:
The MKAnnotation protocol is used to provide annotation-related information to a map view. To use this protocol, you adopt it in any custom objects that store or represent annotation data

(我覺得Apple的文件真的很討厭(本身英文不太好),寫得密密麻麻的看完還不知道怎麼用QQ)
還好上面的敘述看得懂,MKAnnotation是提供給你自定information,什麼意思呢?如果我沒寫過地圖的程式我應該也看不懂吧@@

先看看MKAnnotation裡面定義的東西:

在自定的Annotation裡主要是要設定圖中的title、subtital、coordinate
coordinate -> 設定插針的坐標
title -> 設定顯示的title
subtitl -> 設定顯示的subtitle
設定完上面三件事就會顯示如下圖(ps.針頭是我自定的,所以實際上應該是大頭針的樣子)

上面的三個屬性就是Apple官網上所說的自定information,可以顯示在地圖上面
c. 如何插針sample code
- (void)placeAnnotation{
    
    //設定要插針的經緯度
    CLLocationCoordinate2D currentLocation1 = CLLocationCoordinate2DMake(25.052198, 121.544076);
    CLLocationCoordinate2D currentLocation2 = CLLocationCoordinate2DMake(25.048115, 121.517115);
    CLLocationCoordinate2D currentLocation3 = CLLocationCoordinate2DMake(25.050672, 121.593279);
    
    for(int i = 0;i<3;i++){
        //allocate 一隻針
        MPAnnotation *annotation = [[MPAnnotation alloc]init];
        //設定title和coordinate(此處我沒設定subtitle)
        NSString *str = [[NSString alloc]initWithFormat:@"%@[%d]",@"location",i];
        annotation.title = str;
        annotation.coordinate = location[i];
        [self.mapView addAnnotation:annotation];
    }   
}
在viewDidLoad內打上[self placeAnnotation]就可以看到插上三隻紅色的大頭針
3. 來講一下MKMapViewDelegate的部分
先來看Apple官方的敘述
The MKMapViewDelegate protocol defines a set of optional methods that you can use to receive map-related update messages. Because many map operations require the MKMapView class to load data asynchronously, the map view calls these methods to notify your application when specific operations complete. The map view also uses these methods to request annotation and overlay views and to manage interactions with those views.

上面的敘述簡單來說就是當地圖的資訊更新時,利用實作delegate的方式把更新後的資訊傳給需要的物件(ex:使用者的座標),另外此Delegate提供和Annotation還有overlay互動的method

看完官網的敘述還真有點有看沒有懂得感覺,總之此delegate可以做到兩件事
a. 把地圖更新的資訊傳給delegate物件
b. 自定overlay和annotation的view(ex:把annotation的image改掉)

在這裡先來實作第2項,改變Annotation的view
a. 把delegate設為自己(self.mapView.delegate = self)
b. 在 – mapView:viewForAnnotation:這個method來改變針的樣子
sample code:
sample code比較好懂,下面的code就是在實作自訂的Annotation
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id)annotation{
    
    //表示針可以重用,此method會在插針後才call
    //所以如果針是插好的,物件已經存在,我們只要重用它
    MKPinAnnotationView *marker = (MKPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:@"default"];
    //如果插針是自己,不要改變
    if(annotation == self.mapView.userLocation){
        return nil;
    }
    //如果差針還沒創好,就創一個
    if(!marker){
    
        marker = [[MKPinAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:@"default"];
        //設定針頭不要重天而降
        marker.animatesDrop = NO;
        //改變針頭的顏色為紫色
        marker.pinColor = MKPinAnnotationColorPurple;
    }
    return marker;
}
4. run的結果:

(圖中有overlay的部分) 

沒有留言:

張貼留言