diff --git a/CHANGELOG.md b/CHANGELOG.md index 38231296..310a1f57 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ### main +* Fix iOS compass ignoring `CompassSettings.fadeWhenFacingNorth` (and visibility in general) unless `enabled` was also set. `enabled` and `fadeWhenFacingNorth` are now applied independently, matching the Android behaviour ([#602](https://github.com/mapbox/mapbox-maps-flutter/issues/602)). * Deprecate `MapboxMap.onTapListener` and `MapboxMap.onLongTapListener` in favor of the `MapboxMap.addInterfaction` API. * Add `MapboxMap.httpService.setMaxRequestsPerHost` to cap the number of concurrent HTTP requests per host issued by the underlying HTTP service. Useful for reducing the chance of hitting per-token rate limits during offline tile region downloads. diff --git a/example/integration_test/compass_test.dart b/example/integration_test/compass_test.dart index 642fd31d..95e6faf2 100644 --- a/example/integration_test/compass_test.dart +++ b/example/integration_test/compass_test.dart @@ -53,4 +53,35 @@ void main() { // expect(updatedSettings.image, iconData); } }); + + // Regression test for https://github.com/mapbox/mapbox-maps-flutter/issues/602 + // On iOS `fadeWhenFacingNorth` was ignored unless `enabled` was also passed, + // so it must be applicable on its own and stay consistent with Android. + testWidgets('fadeWhenFacingNorth applies without enabled', + (WidgetTester tester) async { + final mapFuture = app.main(); + await tester.pumpAndSettle(); + final mapboxMap = await mapFuture; + final compass = mapboxMap.compass; + + // Start from a known visible + fading state. + await compass.updateSettings( + CompassSettings(enabled: true, fadeWhenFacingNorth: true)); + expect((await compass.getSettings()).fadeWhenFacingNorth, true); + expect((await compass.getSettings()).visibility, true); + + // Passing only `fadeWhenFacingNorth: false` must stop the fade (iOS: + // .visible) while keeping the compass visible. + await compass.updateSettings(CompassSettings(fadeWhenFacingNorth: false)); + var updatedSettings = await compass.getSettings(); + expect(updatedSettings.fadeWhenFacingNorth, false); + expect(updatedSettings.visibility, true); + + // Passing only `fadeWhenFacingNorth: true` must re-enable the fade (iOS: + // .adaptive) without hiding the compass. + await compass.updateSettings(CompassSettings(fadeWhenFacingNorth: true)); + updatedSettings = await compass.getSettings(); + expect(updatedSettings.fadeWhenFacingNorth, true); + expect(updatedSettings.visibility, true); + }); } diff --git a/ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/CompassController.swift b/ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/CompassController.swift index 26a7aba7..423ca154 100644 --- a/ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/CompassController.swift +++ b/ios/mapbox_maps_flutter/Sources/mapbox_maps_flutter/Classes/CompassController.swift @@ -25,17 +25,21 @@ final class CompassController: CompassSettingsInterface { compass.image = UIImage(data: data, scale: UIScreen.main.scale) } - if let visible = settings.enabled { - let fadeWhenFacingNorth = settings.fadeWhenFacingNorth ?? true + // Apply `enabled` and `fadeWhenFacingNorth` independently so either can be + // changed on its own — matching the Android implementation (CompassMappings.kt). + // Previously visibility was only updated when `enabled` was non-nil, so + // `fadeWhenFacingNorth: false` was silently ignored on iOS and the compass + // kept fading at north. + if settings.enabled != nil || settings.fadeWhenFacingNorth != nil { + let current = compass.visibility + let enabled = settings.enabled ?? (current != .hidden) + let fadeWhenFacingNorth = settings.fadeWhenFacingNorth ?? (current == .adaptive) - let visibility: OrnamentVisibility - switch (visible, fadeWhenFacingNorth) { - case (true, true): visibility = .adaptive - case (true, false): visibility = .visible - case (false, _): visibility = .hidden + switch (enabled, fadeWhenFacingNorth) { + case (true, true): compass.visibility = .adaptive + case (true, false): compass.visibility = .visible + case (false, _): compass.visibility = .hidden } - - compass.visibility = visibility } ornaments.options.compass = compass