<p class="p1"> <span class="Apple-style-span">標:在前一個範例中建立的Google Map上,加上座標點(POIs),當點選座標點會觸發對應的event。 <br/><br/>☉限制:必須將iPhone的作業系統更新到<strong><u><span style="color: rgb(0, 0, 0); ">OS 3.0</span></u></strong>版本,開發使用的SDK也要是<strong><u><span style="color: rgb(0, 0, 0); ">SDK 3.0</span></u></strong>才有內建<strong><span style="color: rgb(255, 0, 0); ">Mapkit Framework</span></strong>。 <br/><br/>☉效果畫面: <br/><a href="http://lh5.ggpht.com/_raFhyN8Oads/ShEEeOHfSuI/AAAAAAAADDg/kYoH8w0UL7o/s1600-h/IMG_0009%5B2%5D.png" style="text-decoration: none; color: rgb(34, 136, 187); "><img title="IMG_0009" border="0" alt="IMG_0009" src="http://hiphotos.baidu.com/zzxap/pic/item/30d2d82493979748d50742d3.jpg" width="320" height="480"/></a><br/><br/>☉步驟說明: <br/>在地圖上每一個座標點,都是一個MKAnnotationView,也就是UI。而每一個MKAnnotationView都需要有對應的資料MKAnnotation,這是Protocal,也就是儲存每個座標點所需要用到的資料的地方。因此,我們要先建立一個使用MKAnnotation的類別。 <br/><br/>依照iPhone開發者文件的說明。這個Protocal需要宣告三個屬性和一個初始化方法。三個屬性分別是coordinate、title、subtitle,和一個方法initWithCoords。 <br/><br/>下面是MKAnnotation類別的程式碼 POI.h</span></p><pre class="c" name="code">#import <foundation><br/>#import <mapkit><br/>#import <corelocation><br/><br/>@interface POI : NSObject <mkannotation> {<br/><br/> CLLocationCoordinate2D coordinate;<br/> NSString *subtitle;<br/> NSString *title;<br/>}<br/><br/>@property (nonatomic,readonly) CLLocationCoordinate2D coordinate;<br/>@property (nonatomic,retain) NSString *subtitle;<br/>@property (nonatomic,retain) NSString *title;<br/><br/>-(id) initWithCoords:(CLLocationCoordinate2D) coords;<br/><br/>@end</mkannotation></corelocation></mapkit></foundation></pre><br/>下面是MKAnnotation類別的程式碼 POI.m<pre class="c" name="code">#import "POI.h"<br/><br/>@implementation POI<br/><br/>@synthesize coordinate,subtitle,title;<br/><br/>- (id) initWithCoords:(CLLocationCoordinate2D) coords{<br/><br/> self = [super init];<br/><br/> if (self != nil) {<br/><br/> coordinate = coords; <br/><br/> }<br/><br/> return self;<br/><br/>}<br/><br/>- (void) dealloc<br/><br/>{<br/> [title release];<br/> [subtitle release];<br/> [super dealloc];<br/>}<br/><br/>@end</pre>宣告了符合MKAnnotation Protocal的類別後,我們就要在Google Map上建立座標點。在iPhone上顯示Google Map的程式可以參考<a href="http://blog.finalevil.com/2009/05/iphoneiphone04-mapkitmkmapviewgoogle.html" style="text-decoration: none; color: rgb(34, 136, 187); "><u><strong>使用MKMapView實作Google Map</strong></u></a>。<br/><br/>接下來,<br/>Step(1):我宣告了一個函式createMapPoint用來建立座標點。在這裡用到了我們在前面宣告的類別POI(這是一個符合MKAnnotation Protocal的類別),我們Create一個POI,接著將座標點所需的經緯度、標題、子標題等訊息都放進去。接著呼叫<pre class="c" name="code">[mapView addAnnotation:poi];</pre>把我們所建立的POI加入地圖(MKMapView)的Annotation集合中。<strong><u><span style="color: rgb(0, 0, 0); ">放入集合的只是<span style="color: rgb(255, 0, 0); ">座標點的資料</span>,這個時候還沒有真正建立座標點</span></u></strong>。<br/><br/>以下是函式createMapPoint的程式碼:<pre class="c" name="code">#import "POI.h"<br/><br/>-(void*) createMapPoint:(MKMapView *)mapView coordinateX:(double)coorX coordinateY:(double)coorY<br/> Title:(NSString*)title Subtitle:(NSString*)subtitle{<br/><br/><br/><br/> if(mapView!=nil){<br/><br/> //set POI lat and lng<br/> CLLocationCoordinate2D p1;<br/> POI *poi;<br/><br/> if(coorX && coorY){<br/><br/> p1.latitude=coorX;<br/> p1.longitude = coorY;<br/> poi = [[POI alloc] initWithCoords:p1]; <br/><br/> if(title!=NULL)<br/> poi.title=title;<br/><br/> if(subtitle!=NULL)<br/> poi.subtitle=subtitle;<br/><br/> [mapView addAnnotation:poi];<br/> [poi release];<br/><br/> }<br/><br/> }<br/> return NULL;<br/>} </pre><br/>Step(2):參考MKMapView的說明文件可以看到<u><strong><span style="color: rgb(0, 0, 0); "><span style="color: rgb(255, 0, 0); ">viewForAnnotation</span>這個方法,這是MKMapView實際建立座標點的地方</span></strong></u>。MKMapView類別在render地圖的時候會依照Annotation集合的資料建立座標點。<pre class="c" name="code">- (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>) annotation{<br/><br/> //方法一:using default pin as a PlaceMarker to display on map<br/> MKPinAnnotationView *newAnnotation = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"annotation1"];<br/> newAnnotation.pinColor = MKPinAnnotationColorGreen;<br/> newAnnotation.animatesDrop = YES; <br/> //canShowCallout: to display the callout view by touch the pin<br/> newAnnotation.canShowCallout=YES;<br/><br/> UIButton *button = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];<br/> [button addTarget:self action:@selector(checkButtonTapped:event:) forControlEvents:UIControlEventTouchUpInside];<br/> newAnnotation.rightCalloutAccessoryView=button; <br/><br/> return newAnnotation;<br/><br/><br/> //方法二:using the image as a PlaceMarker to display on map<br/> /*<br/> MKAnnotationView *newAnnotation=[[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"annotation1"];<br/> newAnnotation.image = [UIImage imageNamed:@"icon.png"];<br/> newAnnotation.canShowCallout=YES;<br/> return newAnnotation;<br/> */<br/>}<br/></pre><br/>Annotation集合中有幾筆資料vieForAnnotation方法就會被執行幾次。因此每次viewForAnnotation被執行,我們都要建立一個MKAnnotationView物件的實體,並且return這個實體。 MKMapView接收到MKAnnotationView的實體就會將它顯示在地圖上,這就是我們想要顯示在地圖上的座標點。在上面程式碼中使用了MKPinAnnotationView這個物件是繼承自MKAnnotationView,作用就是在地圖上顯示一個大頭釘。你可以用<pre class="c" name="code">annotationView.pinColor = MKPinAnnotationColorGreen; </pre><strong><u><span style="color: rgb(0, 0, 0); ">設定大頭釘的顏色</span></u></strong>,不過只有紅色、紫色、綠色,三種顏色(似乎有點稀少XD)。 <br/><br/><pre class="c" name="code">newAnnotation.canShowCallout=YES; </pre><u><strong><span style="color: rgb(0, 0, 0); ">設定在點選大頭釘的時候氣泡視窗是否會談出來</span></strong></u>。第10行到第12行動態建立了一個DetailDisclousue類型的按鈕,替這個按鈕設置了一個UIControlEventTouchUpInside事件,並將它放入氣泡視窗的AccessoryView中。最後,將建立好的座標點回傳給MapView。 被註解的方法二是直接使用MKAnnotationView建立座標點,並且設置她的image屬性,<strong><u><span style="color: rgb(255, 0, 0); ">因此座標點不一定是大頭釘</span></u></strong>,可以有更多的變化與花樣。 <br/><br/><pre class="c" name="code">- (void)checkButtonTapped:(id)sender event:(id)event{<br/><br/> UIAlertView *tmp= [[UIAlertView alloc] initWithTitle:@"訊息!" message:@"Callout測試" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];<br/> [tmp show];<br/> [tmp release];<br/>} </pre>上面是UIControlEventTouchUpInside事件所執行的事件處理常式。當點選DetailDisclousue按鈕後,就會跳出一個alert,表示這個event有正確無誤的被處理。<br/><br/>從這個範例,我們可以看到MKAnnotation和MKAnnotationView之間的關係。<br/><p/><p/>