Подтвердить что ты не робот

React-native: scrollview внутри panResponder

Я использую ScrollView внутри PanResponder. На Android он отлично работает, но на iOS ScrollView не будет прокручиваться. Я провел некоторое расследование, и вот некоторые факты:

  • Если я поместил точку останова в PanResponder.onMoveShouldSetPanResponder(), перед тем, как я перейду, scrollView будет прокручиваться как обычно, но как только я освобожу точку прерывания, scrollView перестанет работать.

  • Если я изменяю ScrollResponder.js и возвращаю true в scrollResponderHandleStartShouldSetResponderCapture() - он использовал для возврата false во время выполнения; и возвращает false в scrollResponderHandleTerminationRequest(), scrollView работает нормально, но, конечно, поскольку он проглатывает событие, внешний PanResponder не получит событие.

Итак, вопросы:

  • Я хочу заставить scrollview работать, а не - усвоить событие. Кто-нибудь знает, что такое подход?
  • Как работает система реагирования на iOS? Реактор-ответчик-ответчик не объясняет это мне.
4b9b3361

Ответ 1

В PanResponder это событие, которое возвращает текущую позицию касания. Вы можете использовать это, чтобы сравнить 2 значения для выполнения прокрутки.

Ответ 2

Я наконец-то решил эту проблему, обернув представление прокрутки внутри представления, и установил стиль просмотра прокрутки на ограниченной высоте.

import * as React from 'react';
import { Text, View, StyleSheet,PanResponder,Animated,ScrollView,Dimensions} from 'react-native';
import { Constants } from 'expo';

const WINDOW_WIDTH = Dimensions.get("window").width;
const WINDOW_HEIGHT = Dimensions.get("window").height;
// You can import from local files

export default class App extends React.Component {
  constructor(props){
    super(props);
    this.minTop = 100;
    this.maxTop = 500;
    this.state={
      AnimatedTop:new Animated.Value(0),
    }
  }

  componentWillMount(){
    let that = this;
    this._previousTop = 100;
    this._panResponder = PanResponder.create({
      onMoveShouldSetPanResponder(){
        return true;
      },
      onPanResponderGrant(){
        that._previousTop = that.state.AnimatedTop.__getValue();
        return true;
      },
      onPanResponderMove(evt,gestureState){
        let currentTop = that._previousTop + gestureState.dy;
        that.state.AnimatedTop.setValue(that._previousTop+gestureState.dy);

      },
      onPanResponderRelease(){

      }
    })
  }


  render() {
    return (
      <View style={styles.container}>
        <Animated.View
          style={[styles.overlay,{top:this.state.AnimatedTop}]}
          {...this._panResponder.panHandlers}
        >
          <View style={{height:200,backgroundColor:"black"}}></View>
          <View>
            <ScrollView
              style={{height:500}}
            >
              <View style={{backgroundColor:"blue",height:200}}></View>
              <View style={{backgroundColor:"yellow",height:200}}></View>
              <View style={{backgroundColor:"pink",height:200}}></View>
              <View style={{backgroundColor:"red",height:200}}></View>
            </ScrollView>
          </View>
        </Animated.View>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    paddingTop: Constants.statusBarHeight,
    backgroundColor: '#ecf0f1',
    padding: 8,
  },
  overlay:{
    position:"absolute",
    width:WINDOW_WIDTH,
    height:WINDOW_HEIGHT-100,
  }
});

введите описание ссылки здесь, я потратил много времени, чтобы решить эту проблему. Надеюсь, это поможет кому-то запутаться с той же проблемой.

Ответ 3

Я не знаю, полезно ли это сейчас, но вы можете добавить эту строку,

return !(gestureState.dx === 0 && gestureState.dy === 0)

в свойстве "onMoveShouldSetPanResponder" объекта PanResponder с параметрами evt и gestState в качестве параметров.

Ваш PanResponder должен выглядеть так:

this._panResponder = PanResponder.create({
  onMoveShouldSetPanResponder(evt, gestureState){
    return !(gestureState.dx === 0 && gestureState.dy === 0)
  },
  onPanResponderGrant(){
    that._previousTop = that.state.AnimatedTop.__getValue();
    return true;
  },
  onPanResponderMove(evt,gestureState){
    let currentTop = that._previousTop + gestureState.dy;
    that.state.AnimatedTop.setValue(that._previousTop+gestureState.dy);

  },
  onPanResponderRelease(){

  }
})

Ответ 4

Я не уверен, что вы все еще нуждаетесь в этом или нет, но я также стану помогать другим.

Если вы помещаете panResponder в представление для сестры ScrollView, ScrollView ведет себя правильно. то вы можете расположить этот вид сестры

здесь example обходного пути.