diff --git a/Sources/MapLibreSwiftUI/MapViewCoordinator.swift b/Sources/MapLibreSwiftUI/MapViewCoordinator.swift index f3e0a2c..f07a779 100644 --- a/Sources/MapLibreSwiftUI/MapViewCoordinator.swift +++ b/Sources/MapLibreSwiftUI/MapViewCoordinator.swift @@ -182,10 +182,13 @@ MLNMapViewDelegate { // Cancel any existing camera update completion task. cameraUpdateTask?.cancel() - cameraUpdateContinuation = nil cameraUpdateTask = Task { @MainActor in return await withCheckedContinuation { continuation in + // Clean up the continuation if it was already set. + cameraUpdateContinuation?.resume() + cameraUpdateContinuation = nil + // Store the continuation to be resumed in mapViewDidBecomeIdle cameraUpdateContinuation = continuation @@ -234,14 +237,13 @@ MLNMapViewDelegate { mapView.userTrackingMode = .follow - mapView.setZoomLevel(zoom, animated: false) + mapView.zoomLevel = zoom mapView.direction = direction mapView.minimumPitch = pitch mapView.maximumPitch = pitch mapView.minimumPitch = pitchRange.rangeValue.lowerBound mapView.maximumPitch = pitchRange.rangeValue.upperBound - } else { mapView.setUserTrackingMode(.follow, animated: animated) { guard mapView.userTrackingMode == .follow else { @@ -249,20 +251,13 @@ MLNMapViewDelegate { return } + mapView.zoomLevel = zoom + mapView.direction = direction + + mapView.minimumPitch = pitch + mapView.maximumPitch = pitch mapView.minimumPitch = pitchRange.rangeValue.lowerBound mapView.maximumPitch = pitchRange.rangeValue.upperBound - let camera = mapView.camera - camera.heading = direction - camera.pitch = pitch - - let altitude = MLNAltitudeForZoomLevel( - zoom, - pitch, - mapView.camera.centerCoordinate.latitude, - mapView.frame.size - ) - camera.altitude = altitude - mapView.setCamera(camera, animated: animated) } } case let .trackingUserLocationWithHeading(zoom: zoom, pitch: pitch, pitchRange: pitchRange): @@ -272,12 +267,13 @@ MLNMapViewDelegate { // Needs to be non-animated or else it messes up following mapView.userTrackingMode = .followWithHeading - mapView.setZoomLevel(zoom, animated: false) + + mapView.zoomLevel = zoom + mapView.minimumPitch = pitch mapView.maximumPitch = pitch mapView.minimumPitch = pitchRange.rangeValue.lowerBound mapView.maximumPitch = pitchRange.rangeValue.upperBound - } else { mapView.setUserTrackingMode(.followWithHeading, animated: animated) { guard mapView.userTrackingMode == .followWithHeading else { @@ -285,19 +281,12 @@ MLNMapViewDelegate { return } + mapView.zoomLevel = zoom + + mapView.minimumPitch = pitch + mapView.maximumPitch = pitch mapView.minimumPitch = pitchRange.rangeValue.lowerBound mapView.maximumPitch = pitchRange.rangeValue.upperBound - let camera = mapView.camera - - let altitude = MLNAltitudeForZoomLevel( - zoom, - pitch, - mapView.camera.centerCoordinate.latitude, - mapView.frame.size - ) - camera.altitude = altitude - camera.pitch = pitch - mapView.setCamera(camera, animated: animated) } } case let .trackingUserLocationWithCourse(zoom: zoom, pitch: pitch, pitchRange: pitchRange): @@ -307,12 +296,12 @@ MLNMapViewDelegate { // so let's do something else instead. // Needs to be non-animated or else it messes up following - mapView.setZoomLevel(zoom, animated: false) + mapView.zoomLevel = zoom + mapView.minimumPitch = pitch mapView.maximumPitch = pitch mapView.minimumPitch = pitchRange.rangeValue.lowerBound mapView.maximumPitch = pitchRange.rangeValue.upperBound - } else { mapView.setUserTrackingMode(.followWithCourse, animated: animated) { guard mapView.userTrackingMode == .followWithCourse else { @@ -320,23 +309,19 @@ MLNMapViewDelegate { return } + mapView.zoomLevel = zoom + + mapView.minimumPitch = pitch + mapView.maximumPitch = pitch mapView.minimumPitch = pitchRange.rangeValue.lowerBound mapView.maximumPitch = pitchRange.rangeValue.upperBound - - let camera = mapView.camera - - let altitude = MLNAltitudeForZoomLevel( - zoom, - pitch, - mapView.camera.centerCoordinate.latitude, - mapView.frame.size - ) - camera.altitude = altitude - camera.pitch = pitch - mapView.setCamera(camera, animated: animated) } } case let .rect(boundingBox, padding): + mapView.minimumPitch = 0 + mapView.maximumPitch = 0 + mapView.direction = 0 + mapView.setVisibleCoordinateBounds(boundingBox, edgePadding: padding, animated: animated, diff --git a/Tests/MapLibreSwiftUITests/MapViewCoordinator/MapViewCoordinatorCameraTests.swift b/Tests/MapLibreSwiftUITests/MapViewCoordinator/MapViewCoordinatorCameraTests.swift index 8acb94a..cdaf06d 100644 --- a/Tests/MapLibreSwiftUITests/MapViewCoordinator/MapViewCoordinatorCameraTests.swift +++ b/Tests/MapLibreSwiftUITests/MapViewCoordinator/MapViewCoordinatorCameraTests.swift @@ -174,8 +174,8 @@ final class MapViewCoordinatorCameraTests: XCTestCase { .setCalled(1) verify(maplibreMapView) - .setZoomLevel(.value(10), animated: .value(false)) - .called(1) + .zoomLevel(newValue: .value(10)) + .setCalled(1) } @MainActor func testUserTrackingWithCourseCameraUpdate() async throws { @@ -219,8 +219,8 @@ final class MapViewCoordinatorCameraTests: XCTestCase { .setCalled(1) verify(maplibreMapView) - .setZoomLevel(.value(10), animated: .value(false)) - .called(1) + .zoomLevel(newValue: .value(10)) + .setCalled(1) } @MainActor func testUserTrackingWithHeadingUpdate() async throws { @@ -264,8 +264,8 @@ final class MapViewCoordinatorCameraTests: XCTestCase { .setCalled(1) verify(maplibreMapView) - .setZoomLevel(.value(10), animated: .value(false)) - .called(1) + .zoomLevel(newValue: .value(10)) + .setCalled(1) } // TODO: Test Rect & Showcase once we build it!