【问题标题】:React Native PanResponder onStartShouldSetPanResponder locationX varies by platformReact Native PanResponder onStartShouldSetPanResponder locationX 因平台而异
【发布时间】:2021-03-28 20:57:10
【问题描述】:

我是 RN 手势 api 的新手,所以如果其中任何一个看起来是根本不正确的方法,我将非常感谢您的反馈以及任何关于查看位置的建议。谢谢! ????

目标

  • 使用 PanResponder api 仅处理点击和滑动手势
  • 使用onStartShouldSetPanResponder 仅处理点击和预移动滑动
  • 保证onStartShouldSetPanResponder处理的event.nativeEvent具有相对于ListComponent的定位信息,而不是列表组件的子项。

根据我是否通过 expo 的本地 web 服务器和 expo ios 应用程序进行测试,以下代码会收到不同的 event.nativeEvent。考虑到底层基础设施的不同,这似乎是合理的。

我的预感是,在 ios 上,onStartShouldSetPanResponder 处理程序触发“太晚”(或太早?),也就是说,手势被归因于子组件,因此冒泡到该处理程序的事件具有相对定位到子组件,而不是下面渲染函数中的列表组件。

const panResponder = useRef(
  PanResponder.create({
    onStartShouldSetPanResponder: (event: GestureResponderEvent) => {
      console.log(event.nativeEvent.locationX)
      updateSelectionValue(event.nativeEvent.locationX) // does some math and conditionally updates local state
    },
    onStartShouldSetPanResponder: () => true,
    onPanResponderMove: handleSwipe,
  })
).current

return (
  <View onLayout={handleLayout} {...panResponder.panHandlers}>
    <ListComponent proportion={selectionValue} {...props} />
  </View>
)

鉴于列表组件是 300 像素宽,并且列表组件中有 3 个 100 像素宽的项目,从列表组件左侧点击大约 5/6 的宽度会产生 ~250/300 的位置 X(正确)网页版和 ios 版 50/300。

List     [----------------300px----------------]
Children [---100px---][---100px---][---100px---]
Tapping Here ---------------------------^^

似乎在 ios 上,事件相对于第三个 100px 宽的子元素定位。

附加上下文:

node --version
v15.12.0

"dependencies": {
  "expo": "~40.0.0",
  "expo-status-bar": "~1.0.3",
  "react": "16.13.1",
  "react-dom": "16.13.1",
  "react-native": "https://github.com/expo/react-native/archive/sdk-40.0.1.tar.gz",
  "react-native-web": "~0.13.12"
},

【问题讨论】:

    标签: react-native gesture panresponder


    【解决方案1】:

    最终设置了一个引用 onLayout 并忽略 event.nativeEvent 以支持 gestureState.x0gestureState.moveX

    let coords = useRef({ x: -1, y: -1 }).current
    
    const handleLayout = useCallback((event: LayoutChangeEvent) => {
      const { x, y } = event.nativeEvent.layout
      coords = { x: Math.round(x), y: Math.round(y) }
    }, [])
    ...
    const panResponder = useRef(
     PanResponder.create({
       onStartShouldSetPanResponder: () => true,
       onPanResponderStart: (event, gestureState) =>
       updateSelectionValue(gestureState.x0 - coords.x),
       onPanResponderMove: (event, gestureState) =>
       updateSelectionValue(gestureState.moveX - coords.x),
      })
    ).current
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-06-11
      • 2016-12-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-23
      • 2023-03-04
      • 1970-01-01
      相关资源
      最近更新 更多