上篇我們說到過在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
