2011年5月9日

iOS SDK with MapKit (Google Map) 練習 (2)

接續上篇,接著繼續分享MKAnnotationView以及MKMapViewDelegate兩個內容;上一篇有提到說顯示在地圖上的資訊註解(Annotations)是由一個資訊模組(MKAnnotation)跟一個可視物件/模組(MKAnnotationView)所組成的,這個可視模組除了將資訊模組裡的資料呈現出來之外,我們還可以將其運用加入圖片跟按鈕,讓我們顯示出來的資訊更加全面。

我會將閱讀文章的人視作對 c / obj-c 以及 iOS有一定的認識,因此在obj-c/c的一些使用內容將不會有太多的解釋。

在這邊我們會先使用MKPinAnnotationView 來介紹 MKAnnotationView 以及 MKMapViewDelegate在顯示MKAnnotationView用的method
//MapKit_PracticeController.h
#import <MapKit/MapKit.h>
#import "Annotation.h"

@interface MapKit_PracticeViewController : UIViewController <MKMapViewDelegate> {
    MKMapView *mapView;
}
//MapKit_PracticeViewController.m
-(void)loadView
{
    [super loadView];
    mapView = [[MKMapView alloc] initWithFrame:CGRectMake(0, 0, 320, 460)];
    mapView.delegate = self;
    MKCoordinateRegion region;
    region.center.latitude = 25.044;
    region.center.longitude = 121.526;
    MKCoordinateSpan span;
    span.latitudeDelta  = .002;
    span.longitudeDelta = .002;
    region.span = span;
    [mapView setRegion:region animated:YES];

    /**
     * 以下照舊 ... 
     */
    [self.view addSubview:mapView];
}
第5,8行的地方我們先將controller採用了MKMapViewDelegate協定,再將mapView的委派指向controller,這樣一來當我們在mapView上的動作就可以反應到我們實作的method上;這邊我們先實作 method
#pragma mark methods for MKMapViewDelegate
- (MKAnnotationView *)mapView:(MKMapView *)map 
            viewForAnnotation:(id <MKAnnotation>)annotation 
{
    static NSString *AnnotationViewID = @"annotationViewID";
    MKPinAnnotationView* pinView = 
    (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationViewID];
    if (!pinView)
    {
 // if an existing pin view was not available, create one
        MKPinAnnotationView* customPinView = 
        [[[MKPinAnnotationView alloc] initWithAnnotation:annotation 
                                         reuseIdentifier:AnnotationViewID] 
         autorelease];                              
        customPinView.pinColor = MKPinAnnotationColorPurple;
        customPinView.animatesDrop = YES;
        customPinView.canShowCallout =YES;
        return customPinView;
    }
    else
    {
        pinView.annotation = annotation;
    }
    return pinView;
}
這個method是當你要呈現的我們在地圖上的資訊註解時所呈現的可視模組(MKAnnotationView),一開始會先判斷這個資訊是否建立過了沒有的話就建立一個新的,有的話就直接使用只是修改資訊內容。
執行結果:
接著我希望我資訊註解可以有相關的照片以及可以點擊顯示更詳細的內容,所以我們要新增修改下列兩個 method
- (MKAnnotationView *)mapView:(MKMapView *)map 
            viewForAnnotation:(id <MKAnnotation>)annotation 
{
    static NSString *AnnotationViewID = @"annotationViewID";
    MKPinAnnotationView* pinView = 
    (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationViewID];
    if (!pinView)
    {
        MKPinAnnotationView* customPinView = 
        [[[MKPinAnnotationView alloc] initWithAnnotation:annotation 
                                         reuseIdentifier:AnnotationViewID] 
         autorelease];                              
        customPinView.pinColor = MKPinAnnotationColorPurple;
        customPinView.animatesDrop = YES;
        customPinView.canShowCallout =YES;
        customPinView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
        customPinView.leftCalloutAccessoryView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"Pic_image.png"]];
        return customPinView;
    }
    else
    {
        pinView.annotation = annotation;
    }
    return pinView;
}
//AnnotationView's UIControl 被點擊後的動作反應
-(void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
    [[[[UIAlertView alloc] initWithTitle:view.annotation.title 
                                 message:view.annotation.subtitle 
                                delegate:nil 
                       cancelButtonTitle:@"OK" 
                       otherButtonTitles:nil, nil] 
      autorelease] 
     show];
}
執行畫面




除了用大頭針外,也是可以自定資訊註解的圖形,只要使用MKAnnotationView來取代MKPinAnnotationView就可以了,並且將MKAnnotationView的image指定成要使用的圖形就可以了,不過要注意的是載入圖形後要使用centerOffset去調整圖形的位置,不然定點會出現一些誤差。
最後在介紹
- (void)mapView:(MKMapView *)map regionDidChangeAnimated:(BOOL)animated
這個method是當你移動你地圖完畢的時候反應的動作,可以在這邊判斷現在在地圖裡面的資訊哪些已經離開畫面需要被移除的或者是需要被新增加到地圖上。在請大家自己試看看該怎麼做囉。

這次的分享內容是補足上一篇沒打完的部份,所以內容比較少了些,有一些地方也是用敘述來帶過,可能要麻煩大家自己嘗試一下會比較清楚;最後就是內容有錯誤或者是有什麼指教的地方,也請大家跟我反應,希望這篇分享也可以幫助倒有需要的人,謝謝。


參考連結:
Introduction to MapKit on iOS Tutorial Link
Map Kit Framework Reference Link
MKMapViewDelegate Protocol Reference Link
MKAnnotationView Class Reference Link

3 則留言:

  1. Facebook點讚好像有點怪怪的 有人知道怎麼解決嗎?

    回覆刪除
  2. 您好,我前一部份實作都沒問題,可是這篇的教學,我照做後執行沒有同樣的效果,不知道方不方便提供程式碼
    信箱:d5321305@yahoo.com.tw,謝謝

    回覆刪除
  3. 調理清晰, 結構明確, 寫得非常好 !!!

    回覆刪除