Mapbox で タップ位置の情報取得+ポップアップ表示
やりたいこと
- タップ時にポップアップを出したい
- ピンのタップの場合はピンの情報を取得
今後用
- iPad, iPhone 両方で使うことを考えると、詳細情報表示/操作は inspector か sheet でやるのが良いか
- ということで 座標と ピン情報が取得できるところまでで完了とする
- queriedFeature からの情報取得は 煩雑で可読性も悪いので、 utility 関数的なのを用意しておいたほうが楽そうだ
@State var selectedFeature
のように選択したもの保持しといて、ハイライトに使うのも良さそう- onLayerTapGesture は 15pt だとタップするには狭い。でもピンのサイズは大きくしたくない
- opacity 薄めか透明で、広めに取った CircleLayer を重ねておけば良いはず(試してない)
- もしかすると shadow も、この方式で作れば良い? (circleBlur)
サンプル
swift
import SwiftUI
import MapboxMaps
struct MapboxView: View {
@State private var popupCoordinate: CLLocationCoordinate2D?
var body: some View {
let center = CLLocationCoordinate2D(latitude: 35.6598, longitude: 139.702389)
let camera = Viewport.camera(center: center, zoom: 13, bearing: 0, pitch: 0)
MapReader { mapReader in
Map(initialViewport: camera) {
VectorSource(id: "parks")
.url("mapbox://takaaki024.99uywdyx")
CircleLayer(id: "parksPoint", source: "parks")
.sourceLayer("parks-9qd2dk")
.circleRadius(10)
.circleColor(UIColor.red)
if let coord = popupCoordinate {
MapViewAnnotation(coordinate: coord) {
VStack(spacing: 4) {
Text("ポップアップ")
.font(.caption)
.padding(6)
.background(Color.white)
.cornerRadius(8)
.shadow(radius: 3)
}
}
}
}
// ★ onTapGesture, onLayerTapGesture は Deprecated らしいが、公式ドキュメントが追いつくまでそのままにしておこう
.onMapTapGesture { context in
// ★ タップ位置の座標をセット (でポップアップ表示)
print("####### onTapGesture | \(context.coordinate)") // 地図上の座標
print("####### onTapGesture | \(context.point)") // 画面上の座標
popupCoordinate = context.coordinate
}
.onLayerTapGesture("parksPoint") { queriedFeature, context in
// ★ 例: ズームアウトしたときは反応しないようにする
guard let zoom = mapReader.map?.cameraState.zoom else {
return false
}
if zoom > 13 {
return false
}
// ★ ピンの情報取得 (公園名を取得)
print("####### onLayerTapGesture | \(queriedFeature) | \(context)")
if let name = (queriedFeature.feature.properties?["name"] as? JSONValue)?.rawValue {
print(name)
}
return true
}
}
.ignoresSafeArea()
}
}