上篇我们说到过在react-native触摸及手势事件
那么我在项目中遇到的问题是在react-navigation中的子页面,希望保留在ios中的效果:从左侧往右侧滑动为退出该页面。
但是希望我在滑动页面的某一部分(视频区域)的时候,不要做出退出页面的操作,页面如下
在手势操作上面红色部分的时候,取消导航的手势返回,在拖动下方区域的时候,启用导航的手势返回
其实在react-navigation组件中,返回的返回手势是要求成为响应者的,我们不能修改react-navigation的默认机制。
但是我们可以动态的要求该页面到底能不能滑动返回:通过设置组件内部的navigationOptions的返回值 gesturesEnabled的取值来规定是否做返回操作
实现方法:
static navigationOptions = ({ navigation }) => {
const { params } = navigation.state;
return {
gesturesEnabled: params && params.enableGestures
};
};
一种简单的实现方式:在视频的上层添加的组件绑定 onPressIn 和 onPressOut事件 , 当按下的时候屏蔽,当抬起的时候允许:
onPressIn={this.eventOnPressIn} onPressOut={this.eventOnPressOut}
eventOnPressIn = (event) => {
console.log(event.nativeEvent);
this.props.navigation.setParams({ enableGestures: false });
};
eventOnPressOut = (event) => {
this.props.navigation.setParams({ enableGestures: true });
};
但是,我们做的视频空间上层本身就应该有手势操作(视频的快进,视频的声音以及亮度调节),所以也可以在手势操作中控制是否允许返回
this._panResponder = PanResponder.create({
// 要求成为响应者:
onStartShouldSetPanResponder: (evt, gestureState) => true,
onStartShouldSetPanResponderCapture: (evt, gestureState) => true,
onMoveShouldSetPanResponder: (evt, gestureState) => true,
onMoveShouldSetPanResponderCapture: (evt, gestureState) => true,
},
onPanResponderMove: (evt, gestureState) => {
// 这里 -------------
this.props.navigation.setParams({ enableGestures: false });
},
onPanResponderTerminationRequest: (evt, gestureState) => true,
onPanResponderRelease: (evt, gestureState) => {
// 这里 --------------
this.props.navigation.setParams({ enableGestures: true });
},
onPanResponderTerminate: (evt, gestureState) => {
},
onShouldBlockNativeResponder: (evt, gestureState) => {
return true;
},
});
this.props.navigation.setParams({ enableGestures: false });
和
this.props.navigation.setParams({ enableGestures: true });
这两行代码的意思是在video上的手势开始拖动时,禁用导航器的手势返回,在拖动完成后,启用导航器的手势返回。
完美解决在导航器页面的某个位置进行手势操作取消/进行导航器的滑动返回
引用解决方案:https://github.com/react-navigation/react-navigation/issues/1274#issuecomment-334359018