ROADTO みちログ

ひとのみちのブログ。大阪でiOSアプリの道を歩くフリーランス。

サンプル MapKit

MapKitとCoreLocationの実装サンプルです。

iOS7.0を前提としています。
storyboardは割愛しています。

まずはframeworkをインポート。
・MapKit.framework
・CoreLocation.framework

ViewControllerクラス。
地図を表示してピンを立てます。

hファイル

#import <MapKit/MapKit.h>
// delegate指定
@interface ViewController : UIViewController <MKMapViewDelegate,CLLocationManagerDelegate>

mファイル

#import <CoreLocation/CoreLocation.h>
#import "CustomAnnotation.h" //ピンのクラス。下記参照。

@interface ViewController ()
@property (strong, nonatomic) IBOutlet MKMapView *mapView; //storyboardで追加したMapView
@property (nonatomic, retain) CLLocationManager *locationManager;

@property NSArray *shopList;//ダミーデータ用リスト
@end

@implementation ViewController

- (void)viewDidLoad
{
    //■■ ダミーデータ ■■ >
    self.shopList = @[
                       @{@"shopNo":@"001", @"shopName":@"イベントガーデン",  	@"ganre": @"バル",        @"lat":@"34.671140", @"lon":@"135.493251"}
                      ,@{@"shopNo":@"002", @"shopName":@"卓球バー",      		@"ganre": @"バー",        @"lat":@"34.672503", @"lon":@"135.494903"}
                      ];
    //■■ ダミーデータ ■■ <
    [super viewDidLoad];
    self.mapView.delegate = self;    

    self.locationManager = [[CLLocationManager alloc] init];
    
    // 位置情報サービスが利用できるかどうかをチェック
    if ([CLLocationManager locationServicesEnabled]) {
        self.locationManager.delegate = self;
        // 測位開始
        [self.locationManager startUpdatingLocation];
    } else {
        NSLog(@"位置情報を使用できません");
    }

    // 初期表示位置を設定
    CLLocationCoordinate2D location;
    location.latitude = 34.67174;         // 経度
    location.longitude = 135.496201;  // 緯度
    [self.mapView setCenterCoordinate:location animated:NO];
    
    // 縮尺を指定
    MKCoordinateRegion region = self.mapView.region;
    region.center = location;
    region.span.latitudeDelta = 0.01;
    region.span.longitudeDelta = 0.01;
    [self.mapView setRegion:region animated:NO];
    
    // ダミーデータ分のピンを作成
    for (NSDictionary* dic in self.shopList) {
        // CustomAnnotationはMKAnnotationを継承したサブクラス。
        // MKAnnotationだけでも使えるが制約が多いので自由なサブクラスをつくることをおすすめ。
        CustomAnnotation* pin = [[CustomAnnotation alloc] init];
        pin.coordinate = CLLocationCoordinate2DMake([dic[@"lat"] floatValue], [dic[@"lon"] floatValue]); // 緯度経度
        pin.title = dic[@"shopName"];//タイトル
        pin.subtitle = dic[@"ganre"];//サブタイトル
        [self.mapView addAnnotation:pin];
    }
    
    // 長押しイベント追加
    UILongPressGestureRecognizer* tapGestureRecognizer
    = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longTap:)];
    [self.mapView addGestureRecognizer:tapGestureRecognizer];
    
}

#pragma mark - MKMapViewDelegate
// マップデータの読み込み開始直前に呼ばれる
-(void)mapViewWillStartLoadingMap:(MKMapView *)mapVie {
    NSLog(@"%s",__func__);
}

// マップデータの読み込み完了後に呼ばれる
-(void)mapViewDidFinishLoadingMap:(MKMapView *)mapView {
    NSLog(@"%s",__func__);
}

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id )annotation
{
    static NSString* Identifier = @"PinAnnotationIdentifier";
    MKPinAnnotationView* pinView =
    (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:Identifier];
    
    // 現在地表示なら nil を返す
    if (annotation == mapView.userLocation) {
        return nil;
    }
    
    if (!pinView) {
        pinView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation
                                                  reuseIdentifier:Identifier];
        pinView.animatesDrop = YES;     // 落下アニメーションありなし
        pinView.canShowCallout = YES;  // 吹き出し表示するか
        pinView.draggable = YES;           // ドラッグできるか
        pinView.rightCalloutAccessoryView =
        [UIButton buttonWithType:UIButtonTypeDetailDisclosure]; // 右側にアクセサリ
    } else {
        pinView.annotation = annotation;
    }
    return pinView;
}

// ピンのアクセサリタップ時のイベント
- (void) mapView:(MKMapView*)_mapView annotationView:(MKAnnotationView*)annotationView calloutAccessoryControlTapped:(UIControl*)control {
    NSLog(@"%s アクセサリタップ",__func__);

     CustomAnnotation* pin = (CustomAnnotation*)annotationView.annotation;
    NSLog(@"title:%@",pin.title);

    // タップしたときの処理

}

#pragma mark - CLLocationManagerDelegate
// 位置情報更新時
- (void)locationManager:(CLLocationManager *)manager
    didUpdateToLocation:(CLLocation *)newLocation
           fromLocation:(CLLocation *)oldLocation {
    NSLog(@"%s 位置情報更新",__func__);
}

// 位置情報利用不可または位置測定失敗などで呼ばれる
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
    NSLog(@"%s 測定失敗",__func__);
}

#pragma mark - action
//  長押しイベント
- (void)longTap:(UILongPressGestureRecognizer*)gestureRecognizer
{
    if (gestureRecognizer.state != UIGestureRecognizerStateBegan) {
        // 開始のみイベント実行する。開始と終了と重複することを回避
        return;
    }
    NSLog(@"%s 長押しイベント",__func__);
    
    // 押した位置を取得
    CGPoint p = [gestureRecognizer locationInView:gestureRecognizer.view];
    CLLocationCoordinate2D coordinate = [self.mapView convertPoint:p
                                          toCoordinateFromView:gestureRecognizer.view];
    //ピンを落とすなどの処理
}
@end


ViewController中で使用されているピンのクラス。
CustomAnnotationクラスはMKAnnotationを継承します。

hファイル

#import <MapKit/MapKit.h>

@interface CustomAnnotation : NSObject <MKAnnotation>
@property (nonatomic, copy) NSString* title;         //吹き出しに表示するタイトル
@property (nonatomic, copy) NSString* subtitle;   //吹き出しに表示するサブタイトル

- (id) initWithCoordinate:(CLLocationCoordinate2D) coordinate;
@end

mファイル

#import "CustomAnnotation.h"

@interface CustomAnnotation ()
@property CLLocationCoordinate2D coordinate;
@end

@implementation CustomAnnotation

- (id) initWithCoordinate:(CLLocationCoordinate2D)c {
	self.coordinate = c;
	return self;
}

実行結果。
f:id:hitonomichi:20140331014914p:plain

現在地が表示されない時は、下記を確認すること。
・シミュレータの設定アプリ-プライバシー-位置情報 で該当アプリがONになっているか確認。
・シミュレータ自体の設定、つまり、デバッグ-位置-位置情報をカスタマイズ の設定を確認。

緯度・経度を簡単に調べたかったらGoogleMap等で調べましょう。

自己紹介
メガネは売っていません
高浜 一道(たかはま かずみち)
大阪でiOSアプリの道を歩くフリーランス。
iPad・iPhoneとサーバを連携した、JSONやDBといったキーワードが出てくるツール系が多めです。
お仕事のご依頼やご連絡はこちらから。
お仕事ください!
Web : ROADTO
ML : k-takahama(a)roadto.jp

個人的なアカウントはこちら。
Tw : @hitonomichi
Fb : kazumichi.takahama