Skip to content

Normalize ornament positioning relative to safe areas on iOS and Android #1137

Description

@vchrisb

Mapbox ornaments such as the logo, attribution button, compass, and scale bar are positioned differently on iOS and Android when the map extends behind system UI.

On iOS, the native Maps SDK treats ornament margins as relative to the MapView safe area. https://docs.mapbox.com/ios/maps/api/10.5.1/Structs/OrnamentOptions.html

On Android, ornament margins are applied relative to the edges of the native map view. System insets are not handled in the same way.

This results in inconsistent ornament positioning between platforms.

There is also a visual alignment difference between the attribution ornament on iOS and Android. On iOS, the attribution is rendered inside a button with additional internal padding, while Android aligns it more closely to the configured ornament margin. As a result, using the same marginLeft for the attribution and logo does not necessarily align their visible content on iOS, even when their ornament frames share the same position.

Current Behavior safe area

The same ornament settings produce different visual positions on iOS and Android.

For example:

await mapboxMap.logo.updateSettings(
  LogoSettings(
    position: OrnamentPosition.BOTTOM_LEFT,
    marginLeft: 8,
    marginBottom: 8,
  ),
);

The expected interpretation is:

8 logical pixels from the bottom-left safe-area boundary

The effective behavior is closer to:

iOS:     safe-area inset + 8
Android: map-view edge + 8

A typical workaround looks like this:

final safeArea = MediaQuery.paddingOf(context);

final bottomMargin = Platform.isAndroid
    ? safeArea.bottom + 8
    : 8;

This workaround must be repeated for every affected ornament and every relevant edge. It also couples application code to a native platform difference that is not represented by the Flutter API.

Current Behavior attribution

For example, an additional iOS-specific offset may be required to visually align the attribution with the logo:

const iOSAttributionContentInset = 8.0;

final attributionLeftMargin = Platform.isIOS
    ? (logoLeftMargin - iOSAttributionContentInset).clamp(0.0, double.infinity)
    : logoLeftMargin;

await mapboxMap.attribution.updateSettings(
  AttributionSettings(
    position: OrnamentPosition.BOTTOM_LEFT,
    marginLeft: attributionLeftMargin,
    marginBottom: 36,
  ),
);

Without this adjustment, the attribution button can appear visually indented compared with the logo on iOS, even when both use the same configured left margin.

Expected Behavior

The Flutter SDK should expose a platform-consistent ornament positioning model.

When safe-area-aware positioning is enabled, ornament margins should be measured from the Flutter view's unobstructed safe-area boundary on both iOS and Android.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions