From d1f5991a87b61e85c046dc34562e45457e692c60 Mon Sep 17 00:00:00 2001 From: Benjamin Demartin Date: Fri, 4 Sep 2026 09:37:52 +0200 Subject: [PATCH] fix(camera): reset maxBounds when the prop is removed Passing null bounds to CameraBoundsOptions leaves the previous value unchanged in the Mapbox SDK, so removing the Camera maxBounds prop kept the old restriction (and setting world bounds manually blocks panning across the antimeridian). Reset to the SDK default (infinite world bounds) instead, on both Android and iOS, matching the existing null-reset handling of minZoom/maxZoom. The RestrictMapBounds example now has a button toggling maxBounds on/off to demonstrate/reproduce this. Co-Authored-By: Claude Fable 5 --- .../rnmbx/components/camera/RNMBXCamera.kt | 2 +- .../src/examples/Camera/RestrictMapBounds.js | 38 +++++++++++-------- ios/RNMBX/RNMBXCamera.swift | 7 +++- 3 files changed, 30 insertions(+), 17 deletions(-) diff --git a/android/src/main/java/com/rnmapbox/rnmbx/components/camera/RNMBXCamera.kt b/android/src/main/java/com/rnmapbox/rnmbx/components/camera/RNMBXCamera.kt index a471e13ca7..6c97d1d05c 100644 --- a/android/src/main/java/com/rnmapbox/rnmbx/components/camera/RNMBXCamera.kt +++ b/android/src/main/java/com/rnmapbox/rnmbx/components/camera/RNMBXCamera.kt @@ -184,7 +184,7 @@ class RNMBXCamera(private val mContext: Context, private val mManager: RNMBXCame val map = mapView.getMapboxMap() val currentBounds = map.getBounds() val builder = CameraBoundsOptions.Builder() - builder.bounds(mMaxBounds?.toBounds()) + builder.bounds(mMaxBounds?.toBounds() ?: CoordinateBounds.world()) // Passing null does not reset this value. builder.minZoom(mMinZoomLevel ?: 0.0) // Passing null does not reset this value. builder.maxZoom(mMaxZoomLevel ?: 25.0) // Passing null does not reset this value. builder.minPitch(currentBounds.minPitch) diff --git a/example/src/examples/Camera/RestrictMapBounds.js b/example/src/examples/Camera/RestrictMapBounds.js index 3d2152daef..a1bb772b71 100644 --- a/example/src/examples/Camera/RestrictMapBounds.js +++ b/example/src/examples/Camera/RestrictMapBounds.js @@ -1,4 +1,5 @@ -import React from 'react'; +import React, { useState } from 'react'; +import { Text } from 'react-native'; import { MapView, Camera, @@ -9,6 +10,7 @@ import { import bboxPolygon from '@turf/bbox-polygon'; import sheet from '../../styles/sheet'; +import Bubble from '../common/Bubble'; const boundsStyle = { fillColor: 'rgba(255, 255, 255, 0.1)', @@ -23,19 +25,25 @@ const bounds = { const { ne, sw } = bounds; const polygon = bboxPolygon([sw[0], sw[1], ne[0], ne[1]]); -const RestrictMapBounds = (props) => ( - <> - - - - - - - -); +const RestrictMapBounds = (props) => { + const [restrictBounds, setRestrictBounds] = useState(true); + return ( + <> + + + + + + + setRestrictBounds(!restrictBounds)}> + {restrictBounds ? 'Remove bounds' : 'Restrict bounds'} + + + ); +}; export default RestrictMapBounds; diff --git a/ios/RNMBX/RNMBXCamera.swift b/ios/RNMBX/RNMBXCamera.swift index bc3f6321a7..db48fc1161 100644 --- a/ios/RNMBX/RNMBXCamera.swift +++ b/ios/RNMBX/RNMBXCamera.swift @@ -339,7 +339,12 @@ open class RNMBXCamera : RNMBXMapAndMapViewComponentBase { options.bounds = try self._toCoordinateBounds(maxBounds) } } else { - options.bounds = nil + // Passing nil does not reset this value, so reset to the SDK default (infinite world bounds). + options.bounds = CoordinateBounds( + southwest: CLLocationCoordinate2D(latitude: -90, longitude: -180), + northeast: CLLocationCoordinate2D(latitude: 90, longitude: 180), + infiniteBounds: true + ) } options.minZoom = self.minZoomLevel?.CGFloat options.maxZoom = self.maxZoomLevel?.CGFloat