我正在try 建立一个可拖动的react 本机应用程序与重新激活和手势处理程序时,我试图实现我的可拖动的边界与重新激活的钳子,在我移动可拖动对象后,应用程序崩溃.

我试着实现了我自己的功能,但仍然使应用程序崩溃.

这是我的代码

const Dragable = props => {
    const translateX = useSharedValue(props.x);
    const translateY = useSharedValue(props.y);
    const isGestureActive = useSharedValue(false);
    const pan = Gesture.Pan()
        .onStart(() => {
            isGestureActive.value = true;
        })
        .onChange((evt) => {
            translateX.value += clamp(evt.changeX,0,200);
            translateY.value +=  clamp(evt.changeY,0,200);
        })
        .onEnd(() => {
            isGestureActive.value = false;
            
        })
    const animatedStyle = useAnimatedStyle(() => {
        const zIndex = isGestureActive.value ? 1000 : 1;
        return {

            zIndex,
            transform: [
                { translateX: translateX.value },
                { translateY: translateY.value },
            ],
        };
    });

    return (
            <GestureDetector gesture={pan}>
                <Animated.View style={animatedStyle}>
                   {some child components}
                </Animated.View>
            </GestureDetector>
    );
};

推荐答案

他们的clamp钩子在我的项目中也不可用,尽管我使用的是3.3.0.一种解决方案是使用自定义挂钩.然而,when react-native-reanimated is installed, the callbacks passed to the gestures are automatically workletized and run on the UI thread when called.因此,使用普通的JAVASCRIPT function会导致崩溃.

  • 一种方法是使用runOnJS(true).
  • 另一种方法是使用worklet个钩子,这只需在钩子及其回调的开头添加"worklet";个.

Run Gesture callback on JS

  const pan = Gesture.Pan()
    .runOnJS(true)
    .onStart(() => {
      // some logic that can call JS hooks
    })
    .onChange(() => {
      // some logic that can call JS hooks
    })
    .onEnd(() => {
      // some logic that can call JS hooks
    });

Run Gesture callback on UI (-= += clampOutRange2zero())

  const clampOutRange2zero = (value, min = null, max = null) => {
    "worklet";
    const shouldClamp =
      (typeof min === "number" && value < min) ||
      (typeof max === "number" && value > max);
    return shouldClamp ? 0 : value;
  };


  const pan = Gesture.Pan()
    .onStart(() => {
      isGestureActive.value = true;
    })
    .onChange((e) => {
      translateX.value += clampOutRange2zero(e.changeX, 0, 200);
      translateY.value += clampOutRange2zero(e.changeY, 0, 200);
    })
    .onEnd(() => {
      isGestureActive.value = false;
    });

Run Gesture callback on UI (= clamp())

  const clamp = (value, min = null, max = null) => {
    "worklet";
    return typeof min === "number" && value < min
      ? min
      : typeof max === "number" && value > max
      ? max
      : value;
  };

  const pan = Gesture.Pan()
    .onStart(() => {
      isGestureActive.value = true;
    })
    .onChange((e) => {
      translateX.value = clamp(translateX.value + e.changeX, 0, 200);
      translateY.value = clamp(translateY.value + e.changeY, 0, 200);
    })
    .onEnd(() => {
      isGestureActive.value = false;
    });

React-native相关问答推荐

AWS Amplify处理后端错误

如何在Recact Native中单击Back按钮后调用函数

应用管理

如何在底部标签导航中添加顶部标签

useState 函数似乎阻止了 Animated.timing 事件?

redux-observable 您在预期流的地方提供了 undefined

React Native 无法读取 index.android.delta

Test suite无法运行 TypeError:Cannot read property ‘default’ of undefined

如何将 View 定位在 ScrollView 的底部?

React Native:无法点击调试菜单

使用 React Navigation 制作离开屏幕的动画

xcode 8.3 框架未找到架构 armv7 的 FileProvider

React Native 创建自定义组件/库

Deprecated Gradle features were used in this build, making it incompatible with Gradle 7.0.

HighLight / ScrollTo - React-Native 上的 ListView、ScrollView

如何在 React Native Android 中设置按钮的高度

Native Script 与 react native 和 ionic 框架的区别

react-navigation模式高度

如何构建一个 react-native 应用程序,以便它在 ipad 上作为 ipad 应用程序运行?

使用行数react-native文本组件