Ответ 1
В PanResponder это событие, которое возвращает текущую позицию касания. Вы можете использовать это, чтобы сравнить 2 значения для выполнения прокрутки.
Я использую ScrollView внутри PanResponder. На Android он отлично работает, но на iOS ScrollView не будет прокручиваться. Я провел некоторое расследование, и вот некоторые факты:
Если я поместил точку останова в PanResponder.onMoveShouldSetPanResponder()
, перед тем, как я перейду, scrollView будет прокручиваться как обычно, но как только я освобожу точку прерывания, scrollView перестанет работать.
Если я изменяю ScrollResponder.js и возвращаю true в scrollResponderHandleStartShouldSetResponderCapture()
- он использовал для возврата false во время выполнения; и возвращает false в scrollResponderHandleTerminationRequest()
, scrollView работает нормально, но, конечно, поскольку он проглатывает событие, внешний PanResponder
не получит событие.
Итак, вопросы:
В PanResponder это событие, которое возвращает текущую позицию касания. Вы можете использовать это, чтобы сравнить 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,
}
});
введите описание ссылки здесь, я потратил много времени, чтобы решить эту проблему. Надеюсь, это поможет кому-то запутаться с той же проблемой.
Я не знаю, полезно ли это сейчас, но вы можете добавить эту строку,
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(){
}
})
Я не уверен, что вы все еще нуждаетесь в этом или нет, но я также стану помогать другим.
Если вы помещаете panResponder в представление для сестры ScrollView, ScrollView ведет себя правильно. то вы можете расположить этот вид сестры
здесь example обходного пути.