上篇我们说到过在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