2017年1月10日火曜日

MapKit Viewのピン(annotation)をタップ動作

前に作った地図表示 + ピン (annotation)で、ピンをクリックしてアクションをする方法を調べてみました。

2つのdelegateを実装する事でピンのタイトルを取得できました
- ピンを配置する際のdelegate
- ピンがタップされる際のdelegate
delegateを実装する前準備(GUI操作)とViewControllerへの継承(コード記述)も必要でした

delegateを実装する
1. (際左ペインで)ViewController.swiftを選択し、左2番目ペインでView Controller Scene - View Controller - View - Disp Mapを選択(最後の名称は自分でつけたもの)
2. 際右ペインにOutlets (delegate) が表示されるので、◉をドラッグし、ViewControllerに接続する
3. ViewController.swiftを選択し、MKMapViewDelegateを継承する
   class ViewController: UIViewController, MKMapViewDelegate {
                              ^この部分
4.   以下のdelegateを追加
  class ViewController: UIViewController, MKMapViewDelegate {
   ...中略...
    // Called when the annotation was added
    func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
        if annotation is MKUserLocation {
            return nil
        }
       
        let reuseId = "pin"
        var pinView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId) as? MKPinAnnotationView
        if pinView == nil {
            pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
           
            pinView?.animatesDrop = true     // 落下アニメーション
            pinView?.canShowCallout = true      // tapのdelegateにはコレが効いている
            pinView?.draggable = true           // ピンをドラッグ出来るようになる
            pinView?.pinTintColor = UIColor.blueColor()  // 色設定

            let rightButton: AnyObject! = UIButton(type: UIButtonType.DetailDisclosure)
            pinView?.rightCalloutAccessoryView = rightButton as? UIView
        }
        else {
            pinView?.annotation = annotation
        }
       
        return pinView
    }
   
    // ピンをタップした際に呼ばれるdelegate
    func mapView(mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
        // どのピンがタップされたかを取得
        let title = view.annotation?.title

        if let point = title{   // "optional(横浜)"となるので、アンラップする http://qiita.com/maiki055/items/b24378a3707bd35a31a8
            let place = "hello " + point!
            print(place)
        }
    }

参考にさせていただきましたサイト
http://blog.koogawa.com/entry/2015/11/01/115728
http://dev.classmethod.jp/smartphone/ios-mapkit/
http://qiita.com/maiki055/items/b24378a3707bd35a31a8

ViewController.swiftの全体
//
//  ViewController.swift
//  mapTest03
//

import UIKit
import MapKit

class ViewController: UIViewController, MKMapViewDelegate { // ピン押下イベントを追加

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    @IBAction func gotoSpot(sender: AnyObject) {
        execGotoSpot()
    }

    @IBOutlet weak var dispMap: MKMapView!
   
    // ピンを表示するボタン押下
    @IBAction func dispPin(sender: AnyObject) {
        let ido = 35.454954
        let keido = 139.631859
        let title = "横浜"
       
        execDispPin(ido, lng: keido, name: title)
    }
   
    // ピンを表示する
    func execDispPin(lat:Double, lng:Double, name:String){
        let annotation = MKPointAnnotation()

        // 位置
        annotation.coordinate = CLLocationCoordinate2DMake(lat, lng)
        // タイトル
        annotation.title = name
        // ピンを置く
        dispMap.addAnnotation(annotation)
    }
   
    // 指定の緯度経度に移動する
    func execGotoSpot(){
        // 横浜の緯度経度
        let ido = 35.454954
        let keido = 139.631859
       
        let center = CLLocationCoordinate2D(latitude: ido, longitude: keido)
       
        // 1500とかだとSIGABRTが発生する(範囲が広すぎるようだ)
        let span = MKCoordinateSpan(latitudeDelta: 0.5, longitudeDelta: 0.5)
       
        let theRegion = MKCoordinateRegion(center: center, span: span)
        dispMap.setRegion(theRegion, animated: true)
    }
   
    // 以下のdelegateを追加
    // Called when the annotation was added
    func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
        if annotation is MKUserLocation {
            return nil
        }
       
        let reuseId = "pin"
        var pinView = mapView.dequeueReusableAnnotationViewWithIdentifier(reuseId) as? MKPinAnnotationView
        if pinView == nil {
            pinView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: reuseId)
           
            pinView?.animatesDrop = true     // 落下アニメーション
            pinView?.canShowCallout = true      // tapのdelegateにはコレが効いている
            pinView?.draggable = true           // ピンをドラッグ出来るようになる
            pinView?.pinTintColor = UIColor.blueColor()  // 色設定

            let rightButton: AnyObject! = UIButton(type: UIButtonType.DetailDisclosure)
            pinView?.rightCalloutAccessoryView = rightButton as? UIView
        }
        else {
            pinView?.annotation = annotation
        }
       
        return pinView
    }
   
    // ピンをタップした際に呼ばれるdelegate
    func mapView(mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
        // どのピンがタップされたかを取得
        let title = view.annotation?.title

        if let point = title{   // "optional(横浜)"となるので、アンラップする http://qiita.com/maiki055/items/b24378a3707bd35a31a8
            let place = "hello " + point!
            print(place)   // "hello 横浜"と表示される
        }
    }
}

0 件のコメント:

コメントを投稿