Cómo crear marcadores con vistas personalizadas

Puedes usar Marker para renderizar jerarquías de View de SwiftUI personalizadas como marcadores en un 3D Map. Los marcadores de vista personalizados te permiten mostrar diseños enriquecidos de SwiftUI, controles interactivos y animaciones ancladas a coordenadas geográficas.

Agrega un marcador de vista personalizado

Para agregar un marcador de vista personalizado a tu Map, declara un Marker dentro del compilador de contenido del mapa, especifica su position con un LatLngAltitude valor y proporciona tu View de SwiftUI personalizada en el cierre content final.

Si omites el cierre content, Marker renderiza una vista predeterminada 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())
      }
    }
  }
}

Personaliza la vista Pin predeterminada

En lugar de crear una View de SwiftUI completamente personalizada, puedes renderizar un pin personalizado pasando un Pin inicializado con un Pin.Configuration al cierre de contenido 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
          )
        )
      }
    }
  }
}

Controla interacciones y animaciones

Como Marker aloja una View de SwiftUI, puedes adjuntar modificadores de gestos de SwiftUI estándares (como .onTapGesture) y animaciones de SwiftUI directamente a la vista dentro del cierre de contenido Marker.

Además, Marker cumple con MapContentAnchorable, lo que te permite anclar un Popover al marcador con el popover(isOpen:autoClosedEnabled:autoPanEnabled:style:content:) modificador:

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")
      }
    }
  }
}

Configura la altitud y el comportamiento de colisión

Puedes personalizar la posición vertical de un Marker y cómo interactúa con las etiquetas o los marcadores superpuestos del mapa pasando parámetros a Marker.init:

  • Modo de altitud: Pasa un AltitudeMode valor al parámetro altitudeMode. De forma predeterminada, Marker usa AltitudeMode.clampToGround.
  • Comportamiento de colisión: Pasa un CollisionBehavior valor al parámetro collisionBehavior (el valor predeterminado es CollisionBehavior.required), y usa collisionPriority (Int?) para especificar la prioridad relativa cuando los marcadores opcionales colisionan (un valor más alto indica una prioridad más alta).