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

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

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

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

```swift
class CustomAnnotation: MKPointAnnotation {

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

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

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

```swift
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を追加することによってエラーが出てくることがあるので、下記の関数も追加してください。

```swift
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をタップしたときに出てくるポップアップに表示されているボタンを押した時のアクションを設定しています。
ボタンを押された時に画面遷移することも可能です。

```swift
//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`文を必要に応じて追加してください。
でわでわ！楽しい開発生活を！！