[Bug]: all of the ref methods of Camera component are not working
Mapbox Implementation
Mapbox
Mapbox Version
default
React Native Version
0.76.3
Platform
Android
@rnmapbox/maps version
10.1.33
Standalone component to reproduce
import React, {useRef} from 'react';
import {
MapView,
ShapeSource,
LineLayer,
Camera,
} from '@rnmapbox/maps';
import {TouchableOpacity ,Text,View} from 'react-native';
function BugReportExample() {
const cameraRef = useRef<Camera>(null);
const locateUser = () => {
// Logic to get user locations
const coords = // This line is working correctly so I am not providing it. console.log(options) shows accurate location etc.;
cameraRef.current.flyTo(coords,10);
}
return (
<View>
<TouchableOpacity onPress={locateUser}>
<Text> Locate </Text>
</TouchableOpacity >
<MapView style={{flex: 1}}>
<Camera ref={cameraRef} zoomLevel={14} />
</MapView>
</View>
);
}
Observed behavior and steps to reproduce
Nothing happens. Also zoomTo, moveTo, setCamera methods are not working. No errors, no warnings. Just not working.
Expected behavior
Camera flies to given coordinates.
Notes / preliminary analysis
No response
Additional links and references
No response
So i have done some brief analysis regarding this issue - if you call cameraRef methods in callback using some button or just call them ~100 miliseconds after view is initialised it works fine.
any solution for this issue?
I found that followUserLocation on the native side initially defaults to true, which caused an issue where cameraRef.current.flyTo didn’t work for me. In this patch (for patch-package), I updated the behavior, and now the cameraRef works as expected.
any solution for this issue?
yes. moved to another map )
I found that
followUserLocationon the native side initially defaults totrue, which caused an issue wherecameraRef.current.flyTodidn’t work for me. In this patch (for patch-package), I updated the behavior, and now thecameraRefworks as expected.
Even though I added your patch, I still face the same issue of .flyTo being useless
useFocusEffect(
useCallback(() => {
if (!coordinates) return;
cameraRef.current?.flyTo(coordinates);
}, [coordinates]),
);
return ( <Camera
ref={cameraRef}
centerCoordinate={currentCoordinates}
followZoomLevel={14}
zoomLevel={14}
/>
)
Any other solutions, help is greatly appreciated
It appears that when followUserLocation is set to true, even after switching it to false, the internal logic in ios/RNMBX/RNMBXCamera.swift overwrites it back to true. As a result, the code in _updateCameraFromTrackingMode is always executed. https://github.com/rnmapbox/maps/blob/0bc19357813e95d51f97b059c50d63a5057f4c12/ios/RNMBX/RNMBXCamera.swift#L494-L502
In my product, I applied a temporary patch to prioritize correct behavior:
diff --git a/node_modules/@rnmapbox/maps/ios/RNMBX/RNMBXCamera.swift b/node_modules/@rnmapbox/maps/ios/RNMBX/RNMBXCamera.swift
index 261245c..72eaebd 100644
--- a/node_modules/@rnmapbox/maps/ios/RNMBX/RNMBXCamera.swift
+++ b/node_modules/@rnmapbox/maps/ios/RNMBX/RNMBXCamera.swift
@@ -493,9 +493,11 @@ open class RNMBXCamera : RNMBXMapComponentBase {
func _updateCamera() {
if let _ = map {
- if followUserLocation {
+ let userTrackingMode = UserTrackingMode(rawValue: self.followUserMode ?? UserTrackingMode.normal.rawValue)
+ if followUserLocation && userTrackingMode != .normal {
self._updateCameraFromTrackingMode()
} else {
+ followUserLocation = false
self._updateCameraFromJavascript()
}
}
If there is a more fundamental solution to this issue, please let me know. Thank you!
bump
This worked for me:
const [center, setCenter] = useState([20, 54]);
useEffect(() =>
setTimeout(() => { // hack
setCenter(props.route.params?.center);
}, 0),
[props.route.params?.center]
);
...
return (
<MapView ... >
<Camera
...
animationMode='easeTo'
animationDuration={1000}
centerCoordinate={center}
/>
</MapView>
)
Tested 10.2.5 with our example Fit component. https://rnmapbox.github.io/docs/examples/Camera/Fit it works fine, on android, so closing this. If still valid issue pls open an issue with a concrete component to reproduce.