mapbox / mapbox-maps-ios

Interactive, thoroughly customizable maps for iOS powered by vector tiles and Metal
https://www.mapbox.com/mapbox-mobile-sdk
Other
479 stars 156 forks source link

Annotations positions and order #2042

Closed OrbitalTech closed 1 year ago

OrbitalTech commented 1 year ago

Environment

Observed behavior and steps to reproduce

I am rebuilding an IOS Application with swiftUI to use the latest mapbox API, what i observed and i couldn't figure out is how do you order annotations so that the user puck will always be on the highest lever?

In the example down below you can see my user puck moving and when we see a view annotation our user puck goes under it which makes it invisible for that time.

Simulator Screenshot - iPhone 15 Pro - 2023-10-24 at 13 13 49

Simulator Screenshot - iPhone 15 Pro - 2023-10-24 at 13 13 48

Simulator Screenshot - iPhone 15 Pro - 2023-10-24 at 13 13 37

The expected behavior is so that the user puck is always on top.

Here is the code for adding the map and annotations:

`@ViewBuilder private var content: some View {

    MapReader { proxy in
        Map(viewport: $viewPort, content: {

            ForEvery(reportViewModel.reports) { report in
                ViewAnnotation(report.coordinate, allowOverlap: true, anchor: .bottom, offsetY: -5) {
                    ReportAnnotation(report: report)
                }
            }

            if showUserPuck {
                createPuck3D()
            }

        })
        .onCameraChanged(action: { camera in
            zoomLevel = camera.cameraState.zoom
            pitchLevel = camera.cameraState.pitch
        })
        .mapStyle(.standard(
            lightPreset: .dawn))
        .ornamentOptions(OrnamentOptions(
            scaleBar: ScaleBarViewOptions(visibility: .hidden),
            compass: CompassViewOptions(visibility: .hidden)))
        .onStyleLoaded(action: { _ in
            proxy.map.map { initStyleLayer($0) }
            configureMap()
        })
    }
}`
persidskiy commented 1 year ago

@OrbitalTech Hi, you are using View Annotations, which are SwiftUI views that are placed on top of the Map. The Puck is rendered inside the map (by metal), so view annotations are always appear on top of the Puck or any other map content.

If you want to place content inside the map, use layer annotations https://docs.mapbox.com/ios/maps/api/11.0.0-beta.6-docc/documentation/mapboxmaps/swiftui-user-guide/#Layer-Annotations

PS: onCameraChanged in your code triggers on every draw call, it's not recommended update @State on every value change, it may lead to high CPU usage, it's better to filter out the values, like

.onCameraChanged { camera in
    showSomethingOnHighZoom = camera.cameraState.zoom > 20
}

Feel free to reopen this issue if my suggestion didn't help