diff --git a/CHANGELOG.md b/CHANGELOG.md index 6038e702cfc8..f6f1227d1617 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ Mapbox welcomes participation and contributions from everyone. * Fix glitch in chained camera animations. * Build XCFramework with `SWIFT_SERIALIZE_DEBUGGING_OPTIONS=NO` flag to avoid serialized search paths in Swift modules. * Fixed a crash that occurs when annotations have duplicate identifiers. +* Expose `MapboxMap.centerAltitudeMode` and ensure correct `centerAltitudeMode` on gesture ending. * Expose extra configuration methods for `MapboxMap`: `setNorthOrientation(_:)`, `setConstrainMode(_:)` and `setViewportMode(_:)`. Use them to configure respective map options after creating a map view. * Expose `MapboxMap.reduceMemoryUse()` which can be used in situations when it is important to keep the memory footprint minimal. diff --git a/Sources/MapboxMaps/Foundation/MapboxMap.swift b/Sources/MapboxMaps/Foundation/MapboxMap.swift index 479678412cc3..d8e1b2ee1f4d 100644 --- a/Sources/MapboxMaps/Foundation/MapboxMap.swift +++ b/Sources/MapboxMaps/Foundation/MapboxMap.swift @@ -820,11 +820,26 @@ public final class MapboxMap: StyleManager { } } + /// Get/set the map centerAltitudeMode that defines how the map center point should react to terrain elevation changes. + /// See ``MapCenterAltitudeMode`` for options. + public var centerAltitudeMode: MapCenterAltitudeMode { + get { __map.getCenterAltitudeMode() } + set { + __map.setCenterAltitudeModeFor(newValue) + gestureState.intrinsicMode = newValue + } + } + + private struct GestureState { + var count: Int + var intrinsicMode: MapCenterAltitudeMode + } + + private lazy var gestureState = GestureState(count: 0, intrinsicMode: centerAltitudeMode) + /// Returns `true` if a gesture is currently in progress. public var isGestureInProgress: Bool { __map.isGestureInProgress() } - private var gestureCount = 0 - /// If implementing a custom gesture, call this method when the gesture begins. /// /// Tells the map rendering engine that there is currently a gesture in progress. This @@ -833,22 +848,25 @@ public final class MapboxMap: StyleManager { /// /// - Note: Must always be paired with a corresponding call to `endGesture()` public func beginGesture() { - gestureCount += 1 - if gestureCount == 1 { - __map.setGestureInProgressForInProgress(true) - __map.setCenterAltitudeModeFor(.sea) - } + gestureState.count += 1 + if gestureState.count == 1 { __map.setGestureInProgressForInProgress(true) } + + /// We should set the center altitude mode to ``MapCenterAltitudeMode.sea`` during gestures to avoid bumpiness when the terrain is enabled. + /// It's not necessary to update ``MapCenterAltitudeMode`` if the user explicitly changed altitude to ``MapCenterAltitudeMode.sea`` before the gesture starts. + if centerAltitudeMode != .sea { __map.setCenterAltitudeModeFor(.sea) } } /// If implementing a custom gesture, call this method when the gesture ends. /// /// - Note: Must always be paired with a corresponding call to `beginGesture()`. public func endGesture() { - assert(gestureCount > 0) - gestureCount -= 1 - if gestureCount == 0 { + assert(gestureState.count > 0) + gestureState.count -= 1 + if gestureState.count == 0 { __map.setGestureInProgressForInProgress(false) - __map.setCenterAltitudeModeFor(.terrain) + + /// After the gesture end we must ensure to set the ``centerAltitudeMode`` expected be the user. + __map.setCenterAltitudeModeFor(gestureState.intrinsicMode) } } } diff --git a/Tests/MapboxMapsTests/Foundation/MapboxMapTests.swift b/Tests/MapboxMapsTests/Foundation/MapboxMapTests.swift index c731af3a70bb..302b632e7980 100644 --- a/Tests/MapboxMapsTests/Foundation/MapboxMapTests.swift +++ b/Tests/MapboxMapsTests/Foundation/MapboxMapTests.swift @@ -296,30 +296,49 @@ final class MapboxMapTests: XCTestCase { func testBeginAndEndGesture() { XCTAssertFalse(mapboxMap.__testingMap.isGestureInProgress()) + XCTAssertEqual(mapboxMap.__testingMap.getCenterAltitudeMode(), .terrain) mapboxMap.beginGesture() XCTAssertTrue(mapboxMap.__testingMap.isGestureInProgress()) + XCTAssertEqual(mapboxMap.__testingMap.getCenterAltitudeMode(), .sea) + mapboxMap.centerAltitudeMode = .terrain mapboxMap.beginGesture() XCTAssertTrue(mapboxMap.__testingMap.isGestureInProgress()) + XCTAssertEqual(mapboxMap.__testingMap.getCenterAltitudeMode(), .sea) mapboxMap.endGesture() XCTAssertTrue(mapboxMap.__testingMap.isGestureInProgress()) + XCTAssertEqual(mapboxMap.__testingMap.getCenterAltitudeMode(), .sea) mapboxMap.beginGesture() XCTAssertTrue(mapboxMap.__testingMap.isGestureInProgress()) + XCTAssertEqual(mapboxMap.__testingMap.getCenterAltitudeMode(), .sea) mapboxMap.endGesture() XCTAssertTrue(mapboxMap.__testingMap.isGestureInProgress()) + XCTAssertEqual(mapboxMap.__testingMap.getCenterAltitudeMode(), .sea) mapboxMap.endGesture() XCTAssertFalse(mapboxMap.__testingMap.isGestureInProgress()) + XCTAssertEqual(mapboxMap.__testingMap.getCenterAltitudeMode(), .terrain) + + mapboxMap.beginGesture() + + XCTAssertTrue(mapboxMap.__testingMap.isGestureInProgress()) + XCTAssertEqual(mapboxMap.__testingMap.getCenterAltitudeMode(), .sea) + + mapboxMap.centerAltitudeMode = .sea + mapboxMap.endGesture() + + XCTAssertFalse(mapboxMap.__testingMap.isGestureInProgress()) + XCTAssertEqual(mapboxMap.__testingMap.getCenterAltitudeMode(), .sea) } func testLoadStyleHandlerIsInvokedExactlyOnce() throws {