カスタムビューでマーカーを作成する

Marker を使用すると、カスタム SwiftUI View 階層を 3D Map のマーカーとしてレンダリングできます。カスタムビュー マーカーを使用すると、地理座標に固定されたリッチな SwiftUI レイアウト、インタラクティブなコントロール、アニメーションを表示できます。

カスタムビュー マーカーを追加する

カスタムビュー マーカーを Map に追加するには、地図コンテンツ ビルダー内で Marker を宣言し、LatLngAltitude 値を使用して position を指定します。また、末尾の content クロージャにカスタム SwiftUI View を指定します。

content クロージャを省略すると、Marker はデフォルトの Pin ビューをレンダリングします。

import GoogleMaps3D
import SwiftUI

struct CustomMarkerExampleView: View {
  var body: some View {
    Map(mode: .hybrid) {
      Marker(
        position: LatLngAltitude(
          latitude: 40.7484,
          longitude: -73.9857,
          altitude: 100.0
        ),
        altitudeMode: .relativeToGround
      ) {
        Text("Empire State Building")
          .padding(.horizontal, 12)
          .padding(.vertical, 6)
          .background(Color.white)
          .clipShape(Capsule())
      }
    }
  }
}

デフォルトのピンビューをカスタマイズする

完全にカスタムの SwiftUI View を作成する代わりに、Pin.Configuration で初期化された Pin を Marker コンテンツ クロージャに渡すことで、カスタマイズされたピンをレンダリングできます。

import GoogleMaps3D
import SwiftUI

struct CustomPinMarkerExampleView: View {
  var body: some View {
    Map(mode: .hybrid) {
      Marker(
        position: LatLngAltitude(
          latitude: 40.7484,
          longitude: -73.9857,
          altitude: 100.0
        ),
        altitudeMode: .relativeToGround
      ) {
        Pin(
          configuration: .init(
            backgroundColor: .blue,
            borderColor: .white
          )
        )
      }
    }
  }
}

インタラクションとアニメーションを処理する

Marker は SwiftUI View をホストするため、標準の SwiftUI ジェスチャー修飾子(.onTapGesture など)と SwiftUI アニメーションを Marker コンテンツ クロージャ内のビューに直接アタッチできます。

また、Marker は MapContentAnchorable に準拠しているため、popover(isOpen:autoClosedEnabled:autoPanEnabled:style:content:) 修飾子を使用して Popover をマーカーに固定できます。

import GoogleMaps3D
import SwiftUI

struct InteractiveMarkerExampleView: View {
  @State private var isPopoverOpen = false

  var body: some View {
    Map(mode: .hybrid) {
      Marker(
        position: LatLngAltitude(
          latitude: 37.7955,
          longitude: -122.3937,
          altitude: 0
        ),
        altitudeMode: .relativeToGround
      ) {
        Pin(configuration: .init(backgroundColor: .black) {
          Image(systemName: "ferry.fill")
            .foregroundStyle(.white)
        })
        .onTapGesture {
          isPopoverOpen.toggle()
        }
      }
      .popover(isOpen: $isPopoverOpen) {
        Text("Ferry Building")
      }
    }
  }
}

高度と重なった場合の動作を構成する

Marker.init にパラメータを渡すことで、Marker の垂直方向の位置や、重なり合う地図ラベルやマーカーとの相互作用をカスタマイズできます。

  • 高度モード: AltitudeMode 値を altitudeMode パラメータに渡します。デフォルトでは、Marker は AltitudeMode.clampToGround を使用します。
  • 重なった場合の動作: CollisionBehavior 値を collisionBehavior パラメータに渡します(デフォルトは CollisionBehavior.required)。collisionPriority(Int?)を使用して、オプションのマーカーが重なった場合の相対的な優先度を指定します(値が大きいほど優先度が高くなります)。