You can use `Marker` to render custom SwiftUI `View` hierarchies as markers on a
3D [`Map`](https://developers.google.com/maps/documentation/maps-3d/ios-sdk/reference/Structs/Map.md.txt).
Custom view markers let you display rich SwiftUI layouts, interactive controls,
and animations anchored to geographic coordinates.

> [!NOTE]
> **Note:** Custom view markers (`Marker`) offer greater customization and interactivity than standard 3D markers ([`Marker3D`](https://developers.google.com/maps/documentation/maps-3d/ios-sdk/reference/Structs/Marker3D.md.txt)), which render with lower overhead. For apps with large numbers of markers, standard [`Marker3D`](https://developers.google.com/maps/documentation/maps-3d/ios-sdk/reference/Structs/Marker3D.md.txt) instances are recommended to maintain optimal performance.

## Add a custom view marker

To add a custom view marker to your
[`Map`](https://developers.google.com/maps/documentation/maps-3d/ios-sdk/reference/Structs/Map.md.txt), declare
a `Marker` inside the map content builder, specify its `position` using a
[`LatLngAltitude`](https://developers.google.com/maps/documentation/maps-3d/ios-sdk/reference/Structs/LatLngAltitude.md.txt)
value, and provide your custom SwiftUI `View` in the trailing `content` closure.

If you omit the `content` closure, `Marker` renders a default
[`Pin`](https://developers.google.com/maps/documentation/maps-3d/ios-sdk/reference/Structs/Pin.md.txt) view.

```swift
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())
      }
    }
  }
}
```

### Customize the default Pin view

Instead of building a completely custom SwiftUI `View`, you can render a
customized pin by passing a
[`Pin`](https://developers.google.com/maps/documentation/maps-3d/ios-sdk/reference/Structs/Pin.md.txt)
initialized with a
[`Pin.Configuration`](https://developers.google.com/maps/documentation/maps-3d/ios-sdk/reference/Structs/Pin/Configuration.md.txt)
to the `Marker` content closure:

```swift
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
          )
        )
      }
    }
  }
}
```

## Handle interactions and animations

Because `Marker` hosts a SwiftUI `View`, you can attach standard SwiftUI
gesture modifiers (such as `.onTapGesture`) and SwiftUI animations directly to
the view inside the `Marker` content closure.

In addition, `Marker` conforms to
[`MapContentAnchorable`](https://developers.google.com/maps/documentation/maps-3d/ios-sdk/reference/Protocols/MapContentAnchorable.md.txt),
which lets you anchor a
[`Popover`](https://developers.google.com/maps/documentation/maps-3d/ios-sdk/reference/Structs/Popover.md.txt)
to the marker using the
[`popover(isOpen:autoClosedEnabled:autoPanEnabled:style:content:)`](https://developers.google.com/maps/documentation/maps-3d/ios-sdk/reference/Protocols/MapContentAnchorable.md.txt#/s:12GoogleMaps3D20MapContentAnchorablePAAE7popover6isOpen17autoClosedEnabled0i3PanK05style7content7SwiftUI08ModifiedD0VyxQrGAJ7BindingVySbG_S2bAA12PopoverStyleVqd__yctAJ4ViewRd__lF)
modifier:

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

## Configure altitude and collision behavior

You can customize how a `Marker` is positioned vertically and how it interacts
with overlapping map labels or markers by passing parameters to `Marker.init`:

- **Altitude mode** : Pass an [`AltitudeMode`](https://developers.google.com/maps/documentation/maps-3d/ios-sdk/reference/Enums/AltitudeMode.md.txt) value to the `altitudeMode` parameter. By default, `Marker` uses [`AltitudeMode.clampToGround`](https://developers.google.com/maps/documentation/maps-3d/ios-sdk/reference/Enums/AltitudeMode.md.txt#/s:12GoogleMaps3D12AltitudeModeO13clampToGroundyA2CmF).
- **Collision behavior** : Pass a [`CollisionBehavior`](https://developers.google.com/maps/documentation/maps-3d/ios-sdk/reference/Enums/CollisionBehavior.md.txt) value to the `collisionBehavior` parameter (defaults to [`CollisionBehavior.required`](https://developers.google.com/maps/documentation/maps-3d/ios-sdk/reference/Enums/CollisionBehavior.md.txt#/s:12GoogleMaps3D17CollisionBehaviorO8requiredyA2CmF)), and use `collisionPriority` (`Int?`) to specify relative priority when optional markers collide (a higher value indicates higher priority).