地図アプリの開発で問題になるポイントをコード付きで解説します。
iPhone/iPad/iPodアプリ開発において、地図と連動させるものを作ろうと思ったら
まず浮かび上がるのがMapKitでしょう。
これは、GoogleMapのSDKであり、GPS機能と連動させて現在位置を表示したり、
マップにピンを立てて目的地を地図付きで説明したりと、
地図情報を使ったアプリではとても重宝します。
(GPSを使った位置情報の取得は別のフレームワークを使用します。)
とても高性能で、とてもよく使うMapKitのGoogleMapですが、
使い方には注意する事があります。
それは、マップ上に表示されるGoogleのロゴです。
もし、仮にMapKitを使用しているのにGoogleロゴが見えない状態になる場合は、
アップルのアプリ申請を通す事は出来ません。
地図のサイズを動的に変更させたり、カーナビや道案内等で地図を回転させたりすると、
結構Googleロゴが隠れてしまう事があります。
しかし、そんな状態で申請しても、アップルは容赦なくリジェクトしてきます。
MapKitを使う限り、Googleロゴは必ず見えるようにしておく必要があります。
今回は、そんなGoogleロゴの位置を変更する方法です。
Googleロゴのインスタンスを取得する方法でもあるので、
位置を動的に変更する事も可能です。
Googleロゴのインスタンスを取得しよう
概要から説明致しますと、MapKitのViewをオーバーライドし、
その上で自分のViewの中からロゴを探しだしてインスタンスをキャッチします。
まずはいきなり答えですがコードを参照して下さい。
ヘッダファイルは下記の様に記述します。
MKMapView+Additions.h
#import <Foundation/Foundation.h> #import <MapKit/MapKit.h> @interface MKMapView (Additions) @end
MapKitのMKMapViewですね。
続いて実装内容は下記の通りです
MKMapView+Additions.m
#import "MKMapView+Additions.h"
@implementation MKMapView (Additions)
//------------------------------------------------------------------------------
// グーグルのロゴを見つけ出し、返却する
//------------------------------------------------------------------------------
-(UIImageView*)googleLogo
{
UIImageView* img_view = nil;
for( UIView* sub_view in self.subviews ){
if( [sub_view isMemberOfClass:[UIImageView class]] ){
img_view = (UIImageView*)sub_view;
break;
}
}
return( img_view );
}
@end
MKMapViewが持つViewの中からUIImageViewのものを探し当てます。
self.subviewsを順に走査し、isMemberOfClassのクラス判定にてUIImageViewのものを探しあて、
返却します。
また、MKMap毎(地図毎)にロゴが存在しますので、インスタンスメソッドとして定義してあります。
該当するインスタンスで当メソッドを起動する事によって、
該当のMAPにあるロゴのインスタンスが取得出来ます。
これは、Viewが構築された後に探し当てる事になるので、
ライフサイクル的に言うとviewDidApperの中等で呼び出しましょう。
呼び出し方は下記を参考にして下さい。
実際にロゴを取得し、位置を変更してみよう
早速、先ほど作成したクラスを利用し、
使う側の実装について解説したいと思います。
まずは下記コードをご覧下さい。
hogeMap.h
#import <UIKit/UIKit.h>
#import "MKMapView+Additions.h"
@interface hogeMap : UIViewController <MKMapViewDelegate>
{
// MAPビュー
MKMapView* topMapView;
}
@property (nonatomic,retain) MKMapView* topMapView;
ヘッダでは、先程作成したMKMapView+Additions.hを読み込みます。
そして、MKMapViewとしてメンバを定義します
そして使う側の実装です。
hogeMap.m
#import "hogeMap.h"
@implementation hogeMap
@synthesize topMapView;
//------------------------------------------------------------------------------
// viewの初回構築
//------------------------------------------------------------------------------
-(void)viewDidLoad
{
[super viewDidLoad];
// マップビューの生成
self.topMapView = [[[MKMapView alloc] init] autorelease];
[self.topMapView setFrame:CGRectMake( 0, 0, 640, 960 )];
[self.topMapView setMapType:MKMapTypeStandard];
[self.topMapView setDelegate:self];
[self.mapBaseView addSubview:self.topMapView];
self.topMapView.showsUserLocation = NO;
}
//------------------------------------------------------------------------------
// view表示後の処理
//------------------------------------------------------------------------------
-(void)viewDidAppear:(BOOL)animated
{
// MKMapViewのインスタンスからロゴ取得メソッドを呼び、ロゴを取得する
UIImageView *logo = [self.topMapView googleLogo];
if( logo == nil ) return;
// ロゴのフレームを取得
CGRect frame = logo.frame;
// 位置を決定する
frame.origin.y = 340;
frame.origin.x = 10;
// 位置を反映させる
logo.frame = frame;
// 地図の動きの影響を受けない様にselfに設置
[self.view addSubview:logo];
[super viewDidAppear:animated];
}
//------------------------------------------------------------------------------
// 破棄
//------------------------------------------------------------------------------
-(void)dealloc
{
self.topMapView = nil;
[super dealloc];
}
@end
ポイントとしては、MKMapViewのviewが構築されてから操作する事です。
ですので、viewDidAppearで実装しましょう。
後はフレームを取得出来ますので、サイズや位置、その他のプロパティも
普通のUIImageViewとして扱えます。
これでGoogleロゴを好きな位置、好きなサイズに加工する事が出来ます。
ちなみに、ios6からはデフォルトがGoogleMapでは無くなりましたので、
近いうちにGoogleMapをオーバーレイするやり方と共に
再度解説出来たらと思います。

Categories: