Closed hardcodet closed 2 years ago
subscribed, have similar issue and would love to see a way to handle this!
Same kind of problem here. Not sure if that's related to a LongPress nested into a Pan, but I have to listen for BEGIN on Android and ACTIVE for iOS to have something similar on both platform...
This does not engage with your exact question, but just a note that the LongPressGestureHandler
gesture event payload includes a y
value that updates on drag, so you don't actually need multiple handlers for this use case.
some problem, IOS works fine, no luck on Android,
const translation = useVector();
const panRef = useRef(null);
const longPressRef = useRef(null);
const isDragging = useSharedValue(false);
const translateX = useDerivedValue(() => {
if (isDragging.value) {
return translation.x.value;
}
return withSpring(translation.x.value);
});
const translateY = useDerivedValue(() => {
if (isDragging.value) {
return translation.y.value;
}
return withSpring(translation.y.value);
});
const style = useAnimatedStyle(() => {
return {
position: "absolute",
top: 0,
left: 0,
transform: [
{ translateX: translateX.value },
{ translateY: translateY.value }
],
};
});
const handleLongPressStateChange = (evt) => {
console.log("handleLongPressStateChange");
if (evt.nativeEvent.state == State.ACTIVE) {
console.log("set isDragging to True");
isDragging.value = true;
}
if (evt.nativeEvent.state == State.CANCELLED ||
evt.nativeEvent.state == State.END) {
console.log("set isDragging to False");
isDragging.value = false;
}
};
const onPanGestureEvent = (evt) => {
console.log("onPanGestureEvent");
console.log("isDragging: ", isDragging.value);
if (isDragging.value) {
const {
nativeEvent: { translationX: x, translationY: y },
} = evt;
console.log("onPanGestureEvent onActive change x and y");
translation.x.value = x;
translation.y.value = y;
}
};
function nestingLongPressWithPan() {
return (
<Animated.View width={width} height={height - 100}>
<PanGestureHandler
ref={panRef}
simultaneousHandlers={longPressRef}
onGestureEvent={onPanGestureEvent}
onHandlerStateChange={(evt) => {
console.log("onHandlerStateChange");
if (isDragging.value && evt.nativeEvent.state == State.END) {
console.log("set isDragging to False");
isDragging.value = false;
translation.x.value = 0;
translation.y.value = 0;
}
}}
>
<Animated.View>
<LongPressGestureHandler
ref={longPressRef}
minDurationMs={500}
maxDist={400}
onHandlerStateChange={handleLongPressStateChange}
>
<Animated.View
x="0"
y="0"
style={[style]}
>
<Text>
this text can drag & drop!!!
</Text>
</Animated.View>
</LongPressGestureHandler>
</Animated.View>
</PanGestureHandler>
</Animated.View>
);
}
react: 17.0.1 => 17.0.1 react-native: 0.64.2 => 0.64.2 react-native-gesture-handler: 1.10.3 => 1.10.3
Hi and thank you for such a detailed report! Let me address the issues you have mentioned in order:
LongPressGestureHandler
activating without the delay. There is a chance that it was fixed already but if the problem still persists for you could you provide a minimal reproduction (and preferably open a new issue regarding it as it seems unrelated to this one)?LongPressGestureHandler
has been normalized in https://github.com/software-mansion/react-native-gesture-handler/pull/1610. At the moment on both platforms the handler will get cancelled after moving the finger in the active state but as mentioned in the PR we may add a way to enable the bahavior you were describing on both platforms.enabled={true}
from PanGestureHandler
it works the same on both platforms. That's because when enabled
is changed while the handler is active, it gets cancelled. The problem is that the code responsible for cancelling it runs even when it "changes" from true
to true
. Here is a PR that fixes it: https://github.com/software-mansion/react-native-gesture-handler/pull/1722.@pkvov Hi, I checked the sample you have provided and it's working for me (I tested it on RNGH from the master
branch). I believe that this is the PR that fixed it: https://github.com/software-mansion/react-native-gesture-handler/pull/1618.
@pkvov Hi, I checked the sample you have provided and it's working for me (I tested it on RNGH from the
master
branch). I believe that this is the PR that fixed it: #1618.
Happy to hear that this was fixed. Thank you! Has the fix been released in an alpha version available to the public or are there plans for a release anytime soon that includes this fix?
@NicholasBoccuzzi It has been released: https://github.com/software-mansion/react-native-gesture-handler/releases/tag/2.0.0
Description
I'm trying to get a list (ScrollView) that contains items that can be reordered. I struggled a bit with the implementation, but got it working on iOS like with nested LongPress / PanGesture-Handlers:
I got both the Pan event and the ScrollView working on iOS by setting
activeOffsetX
andactiveOffsetY
as states, which are updated upon LongPress events. The offset defaults to[-100, 100]
, which causes flicks to scroll the all items on the ScrollView. After a long press, I set the offset to[0,0]
, and I can start dragging around the items on the UI. But as I said, that only works on iOS, so there's another distinction between the platforms.On Android, this doesn't work at all. I noticed a few things:
OnActive
event fires). SettingminDurationMs
has no effect whatsoever either.shouldCancelWhenOutside
andminDist
.Here's the relevant code to my items. As said, at runtime, they are rendered as children of a ScrollView parent component:
What's happening
On Android, short flicks do properly scroll the ScrollView. If I long-press and then start dragging, no scrolling happens (that's good), but also no panning. While dragging my finger, I get continuous
LongPress OnActive
events, but I get only onPan OnStart
event but no other pan events (active or end).On iOS, I get simultanous LongPress active / Pan active events, so I can animated the dragged item.
Package versions