On iOS with Google provider React Native Maps' Draggable Marker disables touches outside the MapView until it registers a touch inside the MapView. On Android everything is fine, but for some reason on iOS when I finish dragging a marker on the map and onDragEnd is called, no touch events are registered unless they are on TextInputs. Occasionally a TouchableOpacity will flash momentarily, but it's onPress function is never called. However if I touch inside the MapView, even nowhere near the marker, everything goes back to the way it's supposed to be. It's like react native maps has some finishing event that doesn't occur that forces the focus to stay on the map.
There are a couple tricky things going on but I don't think they're the culprits:
I use setState with onDragStart and onDragEnd to disable the ScrollView parent component, otherwise the dragging gets interrupted by the scroll on Android.
As part of onDragEnd I make a callout with react-native-geocoding, then update the region state. I have commented all this out and it still doesn't work.
The plan is to animate to the new region after the state is updated, but until this is resolved there's no point. Here's my code, or what's left of it after taking out all the commented stuff:
const MapSection = (props) => {
const {
location, setIsDraggingMarker, onDragMarkerEnd, region,
} = props;
const [isLoading, setIsLoading] = useState(false);
const onDragEnd = (e) => {
onDragMarkerEnd(e.nativeEvent.coordinate);
};
if (!isEmpty(location)) {
return (
<View style={styles.mapContainer}>
<MapView
provider={PROVIDER_GOOGLE}
style={styles.mapView}
initialRegion={region}
scrollEnabled={false}
zoomEnabled={false}
rotateEnabled={false}
>
<Marker
draggable
onDragStart={() => setIsDraggingMarker(true)}
onDragEnd={onDragEnd}
coordinate={region}
>
<Image
style={styles.imageStyle}
resizeMode="stretch"
source={require('../../../../assets/images/draggableMarkerPin.png')}
/>
<Callout
style={styles.customCallout}
onPress={() => { }}
>
<View style={styles.callout}>
<Feather
name="move"
size={12}
color="black"
/>
<Text style={{
paddingLeft: 4,
fontSize: 14,
}}
>
Press and drag to fine tune location!
</Text>
</View>
</Callout>
</Marker>
</MapView>
</View>
);
}
return null;
};
export default MapSection;
//FROM THE PARENT COMPONENT, PASSED AS PROPS
const onDragMarkerEnd = (coords) => {
setIsDraggingMarker(false);
setRegionWithLatLng(coords.latitude, coords.longitude);
};
const setRegionWithLatLng = async (latitude, longitude) => {
const fullLocationData = await geocodeLocationByCoords(latitude, longitude);
const currentLocation = { ...fullLocationData };
const newRegion = {
...region,
latitude: fullLocationData.geometry.location.lat,
longitude: fullLocationData.geometry.location.lng,
};
setRegion(newRegion);
dispatchEventDetailsState({
type: FORM_INPUT_UPDATE, value: currentLocation, isValid: true, input: 'location',
});
};
If there's any way to just trick the MapView into thinking it's been pressed (I'ved tried referencing the MapView and calling mapView.current.props.onPress(), no dice), then I'm fine with that. Just any workaround.