Как получить текущие координаты касания PanResponder относительно родительского вида?

используя React-Native, я пытаюсь захватить события салфетки в элементе представления списка. Все работает хорошо, но у меня возникли трудности с получением текущей координаты жеста касания относительно элемента представления списка.

в своем _handlePanResponderMove, Я использую следующий фрагмент:

let relativeY = event.nativeEvent.locationY;

к сожалению, координата Y, которую я получаю, относится к "дочернему виду", на котором произошел свайп, а не к элементу представления списка (как я ожидал, так как я прикрепил PanResponder к элементу представления списка)

Как я могу получить координату Y жестов относительно родительского представления списка?

2 ответов


установите дочерний вид в pointerEvents="none" вот так:

  <View pointerEvents="none">
        ...
  </View>

таким образом, событие, которое вы получите на свой event.nativeEvent.locationY не будет учитывать мнение ребенка координатами, и что будет делать именно то, что вы хотите.


попробуйте добавить ссылку на ребенка, а затем измерить его относительные расстояния. Этот код представляет собой оболочку с widget (дочерний компонент). Это работает для меня! Заметьте, что this.refs.self.measure является триггером после setTimeout, он не работал без него. Может быть ошибка измерения, или что ссылки не обновляются сразу.

import React, { Component } from 'react'
import TimerMixin from 'react-timer-mixin'
import {
  StyleSheet,
  View,
  TouchableHighlight,
  Text,
  Alert,
  PanResponder,
  Animated,
  Dimensions } from 'react-native'
import BulbWidget from './bulb-widget'

const COLUMNS = 3

export default class Widget extends Component {
  constructor (props) {
    super()
    this.state = {
      pan: new Animated.ValueXY(),
      touches: 1
    }
    this.panResponder = PanResponder.create({
      onStartShouldSetPanResponder: () => true,
      onPanResponderMove: Animated.event([null, {
        dx: this.state.pan.x,
        dy: this.state.pan.y
      }]),
      onPanResponderRelease: (e, gesture) => {
        this.state.pan.flattenOffset()
        this._setPosition(gesture)
        Animated.spring(
          this.state.pan,
          {toValue: {x: 0, y: 0}}
        ).start()
      },
      onPanResponderGrant: (e, gestureState) => {
        this.state.pan.setOffset({x: this.state.pan.x._value, y: this.state.pan.y._value})
        this.state.pan.setValue({x: 0, y: 0})
        this._onPressWidget()
      }
    })
  }

  render () {
    let styleWidget = {}
    this.props.type === 'L' ? styleWidget = styles.widgetL : styleWidget = styles.widget

    return (
      <View ref='self' style={this.state.placed}>
        <Animated.View {...this.panResponder.panHandlers}
          style={[this.state.pan.getLayout(), styleWidget]} >
            <BulbWidget ref='child'/>
        </Animated.View>
      </View>
    )
  }

  componentDidMount () {
    // Print component dimensions to console
    setTimeout(() => {
      this.refs.self.measure((fx, fy, width, height, px, py) => {
        console.log('Component width is: ' + width)
        console.log('Component height is: ' + height)
        console.log('X offset to frame: ' + fx)
        console.log('Y offset to frame: ' + fy)
        this.offset = { fx, fy, width, height }
      })
    }, 0)
  }

  _onPressWidget () {
    this.refs.child.onPressAction()
    this.setState({touches: this.state.touches + 1})
    TimerMixin.setTimeout(() => {
      this.setState({ touches: 1 })
      console.log('Reset')
    }, 1000)

    if (this.state.touches === 2) {
      this.setState({touches: 1})
    }
  }

  _setPosition (gesture) {
    const dx = gesture.moveX - gesture.x0
    const dy = gesture.moveY - gesture.y0

    const { width, height } = this.offset
    const x = Math.abs(this.offset.fx + dx)
    const y = Math.abs(this.offset.fy + dy)

    const idTo = (Math.floor(x / width) + Math.floor(y / height) * COLUMNS)
    this.props.setPosition(gesture, this.props.idx, idTo)
  }
}