地図を長押しして上からピン落とす
プロジェクト作成
Single View Applicationを選択。
Mapkit.frameworkをプロジェクトに登録
プロジェクトのアプリケーションの設定画面で、Mapkit.frameworkを追加
ViewにMKMapViewを追加
StoryBoardの画面で「Map View」をViewに張り付け、「map」と言う名前でOutletの設定を行う。
ViewController.h の@interface宣言に「
@interface ViewController : UIViewController<MKMapViewDelegate> @property (weak, nonatomic) IBOutlet MKMapView *map; @end
初期処理いろいろ
ここからは「ViewController.m」の編集になる。
MapViewの長押しを検出するために「UILongPressGestureRecognizer」を作成してMapViewに追加。
UILongPressGestureRecognizer *longPressGesture; longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPressGesture:)]; [_map addGestureRecognizer:longPressGesture]; _map.delegate = self;
selectorで指定している「handleLongPressGesture」は長押しが検出されたときに
呼び出される関数。
それから、後でピンを追加するときにアニメーションにするため、
MapViewのDelegateにselfをセットしている。
長押し検出時の処理
長押ししたMapViewの画面上の座標値(例:x=150,y=165)を
地図上の座標値(例:latitude:35.674882,longitude:139.772148)に変換するため、
// MKMapView.h - (CLLocationCoordinate2D)convertPoint:(CGPoint)point toCoordinateFromView:(UIView *)view;
を呼び出して変換している。
- (void)handleLongPressGesture:(UILongPressGestureRecognizer *)gesture { if (gesture.state == UIGestureRecognizerStateBegan) { // 長押し検出開始時のみ動作 CGPoint touchedPoint = [gesture locationInView:_map]; CLLocationCoordinate2D touchCoordinate = [_map convertPoint:touchedPoint toCoordinateFromView:_map]; [self setAnnotation:touchCoordinate mapMove:NO animated:NO]; } }
地図にピンを配置
指定した地図上の座標値にピンを立てる。
MKPointAnnotationに座標値を指定するだけ。
このままだとピンが上から落ちてくるアニメーションにはならないため、
後で処理を追加する。
また、ピンの周りに円を表示するため、MKCircleを作成している。
こちらもこのままでは表示されない。
-(void)setAnnotation:(CLLocationCoordinate2D) point mapMove:(BOOL)mapMove animated:(BOOL)animated{ // ピンを全て削除 [_map removeAnnotations: _map.annotations]; // 新しいピンを作成 MKPointAnnotation *anno = [[MKPointAnnotation alloc] init]; anno.coordinate = point; // ピンを追加 [_map addAnnotation:anno]; // ピンの周りに円を表示 MKCircle* circle = [MKCircle circleWithCenterCoordinate:point radius:500]; // 半径500m [_map removeOverlays:_map.overlays]; [_map addOverlay:circle]; }
ピンが落ちてくるアニメーション処理を追加
「animatesDrop = YES」で上から落ちてくるアニメーションになる。
MapViewのDelegateにselfを設定しておかないとこの関数は呼ばれない。
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id )annotation { static NSString* Identifier = @"PinAnnotationIdentifier"; MKPinAnnotationView* pinView; pinView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:Identifier]; if (pinView == nil) { pinView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:Identifier]; pinView.animatesDrop = YES; return pinView; } pinView.annotation = annotation; return pinView; }
ピンの周りの円を描画
ピンの周りに赤い円を描画する処理。
MapViewのDelegateにselfを設定しておかないとこの関数は呼ばれない。
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay { MKCircle* circle = overlay; MKCircleView* circleOverlayView = [[MKCircleView alloc] initWithCircle:circle]; circleOverlayView.strokeColor = [UIColor colorWithRed:1.0 green:0.0 blue:0.0 alpha:0.5]; circleOverlayView.lineWidth = 4.; circleOverlayView.fillColor = [UIColor colorWithRed:1.0 green:0.0 blue:0.0 alpha:0.25]; return circleOverlayView; }