使用自定义视图创建标记

您可以使用 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 的垂直位置以及它与重叠地图标签或标记的互动方式: