要件
Google Maps 上のマーカーをタップした際に吹き出しを表示してください。
Google さんの教え
それ info window でできるよ。
https://developers.google.com/maps/documentation/ios-sdk/marker#add_an_info_window
title
or snippet
のどちらかを設定すれば、マーカーをタップした際に吹き出し( info window )が表示されるようです。
どちらも null
もしくは空文字の場合は吹き出しは表示されません。
let position = CLLocationCoordinate2D(latitude: 51.5, longitude: -0.127)
let marker = GMSMarker(position: position)
marker.title = "London"
marker.snippet = "Population: 8,174,100"
marker.map = mapView
やってみた
やってみました、表示されませんでした。
タップが無視されているような感じだったので isUserInteractionEnabled
を一通り確認しましたが、全て true
でした。
mapView: didTapMarker
怪しげな delegate メソッドが実装されていました。
func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
print(marker)
return true
}
true
を返す場合はこのメソッド内でタップイベントを処理し、 false
を返す場合はイベントを流すようです。
吹き出しを表示する場合はタップイベントを流して、 GMSMarker のデフォルトのタップ時の処理( info window )に任せる必要がありそうです。
ということで、
func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
print(marker)
return false
}
やってみました、表示されませんでした。
ログを確認したところ print(marker)
が出力されていませんでした。
ブレークポイントを貼ってみてもこのメソッドは呼び出されていないようです。
つまり info window の話以前にマーカーがタップイベントを取得できていないという事です。
ちなみに mapView.delegate = self
は適切に設定されています。
他の delegate メソッドが呼び出されることは確認しました。
clusterManager: didTapCluster
怪しげな delegate メソッドが実装されていました。
func clusterManager(_ clusterManager: GMUClusterManager, didTap cluster: GMUCluster) -> Bool {
print(cluster)
return true
}
Cluster とは複数のマーカーがマップ上の近い位置に存在するときに、 1 箇所に纏めて 1 つのアイコンとして表示する機能です。
Google Maps SDK for iOS Utility Library という Google Maps SDK の機能を拡張するためのライブラリに含まれる機能です。
ということで、
func clusterManager(_ clusterManager: GMUClusterManager, didTap cluster: GMUCluster) -> Bool {
print(cluster)
return false
}
やってみました、表示されました。
今回の犯人はこいつでした。
Cluster のアイコンがタップイベントを処理しており、 Marker にイベントが流れてこない状態となっていました。
まなび
基本的には Google さんの教えに従えば吹き出しは表示されます。
今回はイレギュラーなケースでしたが、その際の着眼点を記事に残しておきたいと思いました。
タップが無視されるという現象はアプリ開発をしていると割と頻繁に遭遇します。
これまでの経験では
isUserInteractionEnabled
- UIButton の
isEnabled
- フォーカスの位置
辺りを見ていると大方解決できていました。
delegate の処理でタップイベントを 流す / 流さない を管理するパターンは初めてだったので知見が広がりました。