23
27

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

カスタムクラスを使ったMKAnnotationをMapViewに表示させる

Last updated at Posted at 2016-01-22

追記(2016.03.06)

GitHubにコード公開しました。
https://github.com/black-sleepman/iPhone/tree/master/CustomAnnotationPin

はじめに

mapviewを使ってるとpinの色や経緯度の他にもデータを乗せておきたい!みたいなことありますよね
そんなときは自分でクラス作っちゃいましょう!!

MKAnnotationを継承したCustomAnnotationクラスの作成

class CustomAnnotation: MKPointAnnotation {

    var datas: Dictionary<String, AnyObject>!
    var flag: Bool! = false
}

上のサンプルはpinにDicrionaryとBoolの変数をもたせました。
変数は自分でも増やすことができるので自分の環境用に修正してください。

MapViewにCustomAnnotationピンを表示させる

今回は複数のpinを表示させることを想定して書きます。
使いやすいように関数化して書きます。dataがArray型なのでfor - inを使って簡単に取り出す方法を採用しました。

func parsed(data: Array<Dictionary<String, AnyObject>>) {
	var annotations: [MKAnnotation] = []

	for datas in data {

		let Annotation = CustomAnnotation()

		// coordinate, titleもMKAnnotaionを継承しているので
		// 普通に使うことができます。( MKAnnotationのやつなら全部使えるよ )
		Annotation.coordinate = CLLocationCoordinate2DMake(
									datas["lat"] as! CLLocationDegrees,
									datas["lng"] as! CLLocationDegrees)
		Annotation.title = datas["name"] as? String

		// AnnotationをCustomAnnotation()としているので
		// 上で定義した変数に代入するには以下のように
		Annotation.datas = datas
		Annotation.flag  = false

		annotations.append( Annotation )
	}
	
	self.mapView.addAnnotations(annotations)
}

mapViewに表示するpinをカスタムする

mapViewに表示されるpinにボタンを追加したり、色を変えたりしてみます。
自分のclassにMKMapViewDelegateを追加してください
また、Delegateを追加することによってエラーが出てくることがあるので、下記の関数も追加してください。

class ViewController: UIViewController {
	
	override func viewDidLoad() {
		super.viewDidLoad()
	}
				:
				: 以下省略
				:
}

			↓↓こんな感じで↓↓

class ViewController: UIViewController, MKMapViewDelegate {

	@IBOutlet var mapView: MKMapView
	
	override func viewDidLoad() {
		super.viewDidLoad()
		
		self.mapView.delegate = self
		
		// mapViewの中心を現在地にする
		mapView.setCenterCoordinate(mapView.userLocation.coordinate, animated: true)
		
		// mapの表示方法
		// MKMapType.Standard  - 標準の地図(デフォルト)
		// MKMapType.Satellite - 航空写真
		// MKMapType.Hybrid    - 標準の地図+航空写真
		mapView.mapType = MKMapType.Standard
	}
	
	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 {
            
            // pinを表示するためのViewを取得
            pinView = MKPinAnnotationView( annotation: annotation, reuseIdentifier: reuseId )
            // pinのイベントを許可する
            pinView?.canShowCallout = true
            // pinをタップした時に出てくるポップアップの右側にボタンをつける
            pinView?.rightCalloutAccessoryView = UIButton(type: .InfoLight)
            
            // pinのクラス名を取得(今回の場合は「CustomAnnotation」になります)
            switch NSStringFromClass(annotation.dynamicType).componentsSeparatedByString(".").last! as String {
                
                case "CustomAnnotation":
                
                	// ( annotation as! CustomAnnotation )をしないと
                	// CustomAnnotationクラスで定義した変数が取れないので注意!
                    if ( annotation as! CustomAnnotation ).flag! {
                        // pinの色を紫にする
                        pinView?.pinTintColor = .purpleColor()
                    }
                
                default: break
            }
            
        }
        // すでにpinがカスタマイズされている場合はそのまま表示
        else { pinView!.annotation = annotation }
        
        return pinView
    }

}

ポップアップボタンのアクション設定

ここではpinをタップしたときに出てくるポップアップに表示されているボタンを押した時のアクションを設定しています。
ボタンを押された時に画面遷移することも可能です。

//Click on left or right button
func mapView(mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
        
    // 押されたのがポップアップの右側のボタンならば
	if (control == view.rightCalloutAccessoryView) {
        
        // 押されたボタンのAnnotationのクラスチェック 
        switch NSStringFromClass(view.annotation!.dynamicType).componentsSeparatedByString(".").last! as String {
                
            case "CustomAnnotation":
                print( ( view.annotation as! CustomAnnotation ).datas )
                
            default: break
        }
    }
}

さいごに

これで一通り終了です。CustomAnnotationは名前を変えればいくらでも増やすことができます。
その際はクラスチェックしているswitch - case文を必要に応じて追加してください。
でわでわ!楽しい開発生活を!!

23
27
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
23
27

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?