简体   繁体   中英

How to get current touch coordinates of PanResponder relative to parent view?

Using React-Native, I'm trying to capture swipe events on a list view item. Everything works well but i'm having difficulties acquiring the current coordinate of the touch gesture, relative to the list view item.

In my _handlePanResponderMove , I use the following snippet:

let relativeY = event.nativeEvent.locationY;

Unfortunately, the Y coordinate I'm getting is relative to the "child view" the swipe occurred on, and not relative to the list view item (as I was expecting, since I attached the PanResponder to the list view item)

How can I get the gestures' Y coordinate relative to the list view parent?

Set the child view to pointerEvents="none" like so:

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

That way, the event you receive on your event.nativeEvent.locationY will not take into account the child view coordinates at all, and that will do exactly what you want.

Try to add a ref to the child and then measure its relative distances. This code represents the wrapper with a widget (child component). It works for me! Notice that this.refs.self.measure is trigger after a setTimeout, it was not working without it. Could be a bug of measure or that the references are not updated after an instant.

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)
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM