PanResponder限制为父容器视图

时间:2018-05-31 00:32:40

标签: reactjs react-native

我正在使用PanResponder作为屏幕上的可拖动框,但它当前可以移出屏幕。在阅读(非常令人困惑的)文档而没有示例之后,有没有办法将框限制为不移出屏幕?

以下是我所拥有的:

componentWillMount () {

  this.animatedValue = new Animated.ValueXY()
  this.value = {x: 0, y: 0}
  this.animatedValue.addListener(value => this.value = value)
  this.panResponder = PanResponder.create({
    onStartShouldSetPanResponder: (evt, gestureState) => true,
    onMoveShouldSetPanResponder: (evt, gestureState) => {
      return gestureState.dx !== 0 && gestureState.dy !== 0
    },
    onPanResponderGrant: (e, gestureState) => {
      this.animatedValue.setOffset({
        x: this.value.x,
        y: this.value.y,
      })
      this.animatedValue.setValue({x: 0, y: 0})
    },
    onPanResponderMove: (e, gestureEvent) => {
      this.pan(gestureEvent)
      Animated.event([
        null, {dx: this.animatedValue.x, dy: this.animatedValue.y}
      ])
    },
    onPanResponderRelease: (e, gestureState) => {
      this.animatedValue.flattenOffset()
      Animated.decay(this.animatedValue, {
        velocity: {x: gestureState.vx, y: gestureState.vy}
      }).start()
    }
  })
}

render () {

  return (
    <Animated.View
      {...this.panResponder.panHandlers}
      style={styles.box}
    >
      <Image source={{uri: 'uri'}} style={styles.imageDimensions} />
    </Animated.View>
  )
}

1 个答案:

答案 0 :(得分:0)

我编写了一个基本代码,可以帮助您进行修改。 Animated.View不能移到X坐标的负位置。

import React from 'react';
import { View, Animated, PanResponder } from 'react-native';

let _value = {x: 0, y:0};
const _animatedValue = new Animated.ValueXY();
let xOffset = 0;

export default function App() {

  React.useEffect(()=> {
    const listener = _animatedValue.addListener(
      (value) => _value = value
    );
    return () => {
      _animatedValue.removeListener(listener);
    }
  }, []);

  const panResponder = React.useMemo(() => PanResponder.create({
    onStartShouldSetPanResponder: () => true,
    onMoveShouldSetPanResponderCapture: () => true, // Same here, tell iOS that we allow dragging
    onPanResponderGrant: (_, gesture) => {
      xOffset= (xOffset + gesture.dx >= 0) ? _value.x : 0;
      _animatedValue.setOffset({x: xOffset, y: _value.y});
      _animatedValue.setValue({x: 0, y: 0});
    },
    onPanResponderMove: (_, gesture) => {
      if (xOffset + gesture.dx >= 0) {
        _animatedValue.setValue({ x: gesture.dx, y: 0 });
      } else {
        xOffset = 0;
        _animatedValue.setOffset({x: 0, y: _value.y});
        _animatedValue.setValue({ x: 0, y: 0 });
      }
    },
    onPanResponderRelease: () => {
      _animatedValue.flattenOffset();
    }
  }), []);

  return <View
    style={{
      flex: 1,
      alignItems: 'center',
      alignContent: 'center'
    }}
  >
    <View
      style={{
        width: 500,
        height: 200,
        position: 'relative',
      }}
    >
      <View
        style={{
          width: 500,
          height: 2,
          backgroundColor: 'red',
          top: 100,
          position: 'absolute'
        }}
      >
        <Animated.View
          {...panResponder.panHandlers}
          style={{
            width: 10,
            height: 10,
            backgroundColor: 'blue',
            borderRadius: 5,
            position: 'absolute',
            zIndex: 2,
            transform: _animatedValue.getTranslateTransform()
          }}
        ></Animated.View>
      </View>
    </View>
  </View>

}