🐾
MKMapViewでユーザーの方角を表示し、カメラの自動回転を無効にする
はじめに
MKMapViewでユーザーの方角を表示するには、userTrackingMode
をfollowWithHeading
にすれば良いです。
mapView.userTrackingMode = .followWithHeading
これでユーザーの方向を表示できるのですが、カメラが自動で回転するようになります。
ユーザーの方角表示を自前実装することで、要件を満たすことができたので、方法を共有しようと思います。
実装方針
- ユーザーの現在地を表示する
- 現在地を表すAnnotationの画像を別画像に変更
- ユーザーの方角を取得し、画像を回転させる
1. ユーザーの現在地を表示する
mapView.showsUserLocation = true
2. 現在地を表すAnnotationの画像を別画像に変更
MKMapViewのデリゲートメソッドで、ユーザーの現在地を表すAnnottionの画像を書き換える。
そして、クラス直下でそのAnnotationを保持しておく。
private var userLocationAnnotationView: MKAnnotationView?
func mapView(
_ mapView: MKMapView,
viewFor annotation: MKAnnotation
) -> MKAnnotationView? {
if annotation is MKUserLocation {
var userLocationAnnotation = mapView.dequeueReusableAnnotationView(withIdentifier: "userLocation")
if userLocationAnnotation == nil {
userLocationAnnotation = MKAnnotationView(annotation: annotation, reuseIdentifier: "userLocation")
}
let image = UIImage(systemName: "location.north.circle")
userLocationAnnotation?.image = image
userLocationAnnotation?.annotation = annotation
userLocationAnnotation?.frame = .init(x: 0, y: 0, width: 30, height: 30)
self.userLocationAnnotationView = userLocationAnnotation
return userLocationAnnotation
}
return nil
}
3. ユーザーの方角を取得し、画像を回転させる
CLLocationManagerのデリゲートメソッドで、ユーザーの方向を取得。
func locationManager(_ manager: CLLocationManager, didUpdateHeading newHeading: CLHeading) {
// クラス直下に格納しておいた現在地を表すAnnotation
guard let userLocationAnnotationView = userLocationAnnotationView else { return }
// ラジアンに変換し、画像を回転
let angle = CGFloat(newHeading.trueHeading) * .pi / 180
let transform = CGAffineTransform(rotationAngle: angle)
userLocationAnnotationView.transform = transform
}
最後に
ポイントだけ説明しました。
全体が確認したい方はこちら↓↓
株式会社 カラビナテクノロジーは「命綱や支点を素早く確実に繋ぐカラビナ。そんなカラビナのような役割をテクノロジーで実現したい」という想いのもと、福岡で設立。 主にシステム開発・アプリ開発・ Webサイト制作を行っています。採用情報→karabiner.tech/recruit/requirements/
Discussion