maps icon indicating copy to clipboard operation
maps copied to clipboard

[Bug]: all of the ref methods of Camera component are not working

Open zju1 opened this issue 1 year ago • 8 comments

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

zju1 avatar Nov 29 '24 09:11 zju1

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.

draggie avatar Dec 18 '24 13:12 draggie

any solution for this issue?

yuriydrobniy avatar Jan 20 '25 14:01 yuriydrobniy

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.

@rnmapbox+maps+10.1.33.patch

yuriydrobniy avatar Jan 21 '25 13:01 yuriydrobniy

any solution for this issue?

yes. moved to another map )

zju1 avatar Jan 21 '25 15:01 zju1

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.

@rnmapbox+maps+10.1.33.patch

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

IAlphaOmegaI avatar Jan 26 '25 00:01 IAlphaOmegaI

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!

alternacrow avatar Feb 24 '25 10:02 alternacrow

bump

spyshower avatar May 03 '25 13:05 spyshower

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>
)

xaiamov avatar May 26 '25 18:05 xaiamov

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.

Image

mfazekas avatar Oct 18 '25 11:10 mfazekas