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