在向后滑动时执行操作(反应导航)

Performing action on swipe back (react-navigation)

在 react-navigation 中,知道有一种方法可以在按下后退按钮时执行自定义操作。当用户滑动返回上一个屏幕时,是否有类似的方法来执行此操作?

我能够确定应用程序是通过后退按钮返回还​​是使用路由器的 getStateForAction 功能向后滑动。尝试检查动作和状态变量,以便在需要时对其进行更多微调。

export const ScreensStack = StackNavigator(
{
    Login: {screen: LoginScreen},
    Schedule: {screen: ScheduleScreen},
}

/**
 * Intercept actions occuring in the screen stack.
 */
const getStateForActionScreensStack = ScreensStack.router.getStateForAction;

ScreensStack.router = {
    ...ScreensStack.router,
    getStateForAction(action, state) {
      if (action.type == 'Navigation/BACK') {
        console.log('We are going back...');
      }
      return getStateForActionScreensStack(action, state);
    },
};

react-navigation 文档中有一些示例: https://reactnavigation.org/docs/en/routers.html

我发现当背面来自滑动但在其他类型的背面未定义时,该动作有一个直接参数设置为真:

const MyApp = createStackNavigator({
  Home: { screen: HomeScreen },
  Profile: { screen: ProfileScreen },
}, {
  initialRouteName: 'Home',
})

const defaultGetStateForAction = MyApp.router.getStateForAction;

MyApp.router.getStateForAction = (action, state) => {
  if (state && action.type === 'Navigation/BACK' && action.immediate) {
    console.log('Perform custom action on swipe')
  }
  return defaultGetStateForAction(action, state);
};

在 react-navigation v5.0 中使用它

所以我正在使用 Pan-Responder 来处理 react-native iOS 中的 swipe-back 事件。

我是如何做到的:

在我的 Navigator.js 中,我添加了 gestureEnabled: false 应用程序的功能。

const Funnel = createStackNavigator({
  page1: Page1,
  page2: Page2,
  page3: Page3,
}, {
  // headerMode: 'float',
  defaultNavigationOptions: ({ navigation }) => ({
    ...TransitionPresets.SlideFromRightIOS,
    gestureEnabled: false,
    header:
      (<SafeAreaView style={{ flex: 1 }} forceInset={{ bottom: 'never' }}>
        <AppHeader pageData={navigation.state.params == undefined ? data : navigation.state.params} />
      </SafeAreaView>),
  }),
})

所以通过上面的代码,我能够在 iOS 应用程序中删除向后滑动功能。

现在我必须添加滑动返回功能。

  export let panResponder = (callback) => PanResponder.create({
  onMoveShouldSetResponderCapture: () => true,
  onMoveShouldSetPanResponderCapture: (evt, gestureState) => {
    return Math.abs(gestureState.dx) > 5;
  },
  onPanResponderRelease: (evt, gestureState) => {
    if (Platform.OS != 'ios') return
    if (Math.floor(gestureState.moveX) >= 0 && Math.floor(gestureState.moveX) <= width / 2) {
      callback()
    }
  },
});

因此,通过使用上面的代码,您将获得 swipe-back 事件的回调,您可以在其中添加 navigation.goBack() 功能。

如何在您的视图中添加PanResponser:

 <View {...panResponder(backButtonCallback).panHandlers}/>

React Navigation 5.7 引入了一种简单的方法来执行此操作,无需覆盖返回操作或滑动手势,基本上您可以在组件中拦截返回操作并在它发生之前执行回调:

import {useNavigation} from '@react-navigation/native';

const MyScreenComponent = (props) => {
  const navigation = useNavigation();

  React.useEffect(() => (
    navigation.addListener('beforeRemove', (e) => {
      // Prevent default behavior of leaving the screen (if needed)
      e.preventDefault();

      // Do whatever...
    })
  ), [navigation]);

  // Rest of component
}

在此示例中,我使用 useNavigation 挂钩来访问 navigation 对象,但您也可以从 props 中提取它,这实际上取决于您的应用程序的构建方式。

Official documentation.