I18nManager.forceRTL doesn't applies changes in first app load

后端 未结 5 1790
一生所求
一生所求 2021-02-18 21:37

I have an app that created by awesome React-native and my layout designed to be in RTL mode. I\'ve set up an option for forcing the layout to be RT

相关标签:
5条回答
  • 2021-02-18 22:09

    Make sure that on iOS, next to having added all relevant RTL locales to your Xcode project (e.g. Arabic). You should also make sure that your .ipa contains .lproj folders for each locale. Otherwise iOS doesn't pick up on the supported languages.

    This is a common issue in React Native projects where you don't typically write a lot of Swift/Obj-C code & most of the translations happen in JavaScript (apart maybe from some stuff in you Info.plist).

    0 讨论(0)
  • 2021-02-18 22:15

    I had the same problem and solved it by invoking forceRTL in MainApplication.java in the onCreate method.

    ...
    import com.facebook.react.modules.i18nmanager.I18nUtil;
    
    ...
     @Override
      public void onCreate() {
        super.onCreate();
        SoLoader.init(this, /* native exopackage */ false);
    
        I18nUtil sharedI18nUtilInstance = I18nUtil.getInstance();
        sharedI18nUtilInstance.forceRTL(this,true);
        sharedI18nUtilInstance.allowRTL(this, true);
      }
    ...
    

    On IOS add in the AppDelegate.m

    ...
    NSURL *jsCodeLocation; // this probably already exists!
    [[RCTI18nUtil sharedInstance] allowRTL:YES];
    [[RCTI18nUtil sharedInstance] forceRTL:YES];
    ...
    

    Source

    0 讨论(0)
  • 2021-02-18 22:18

    I went through the same issue this helped me. This is abit modified answer without the need to use redux.

    First you check current state with I18nManager.isRTL then forceRTL if not and restart with react-native-restart.

       constructor(props) {          
          //Force RTL
          if(!I18nManager.isRTL){
             I18nManager.forceRTL(true);
             RNRestart.Restart();
          }
       }
    
    0 讨论(0)
  • 2021-02-18 22:24

    Thats because you should use I18nManager with try and catch! it needs "await" to do his job.

    try {
        I18nManager.allowRTL(false);
      } catch (e) {
        console.log(e);
      }
    

    use it like this, and it will work.

    0 讨论(0)
  • 2021-02-18 22:27

    After a week finally i found a logicly way to solve this issue with using Redux & react-native-restart plugin. I'm also use a nice splash screen to user don't show a restarting progress for this purpose.

    So let's dive into code:

    Redux action:

    export const GET_APP_LAYOUT_DIRECTION = 'GET_APP_LAYOUT_DIRECTION';
    export const SET_APP_LAYOUT_DIRECTION = 'SET_APP_LAYOUT_DIRECTION';
    
    export const getAppLayoutDirection = () => ({
      type: GET_APP_LAYOUT_DIRECTION,
    });
    
    export const setAppLayoutDirection = direction => ({
      type: SET_APP_LAYOUT_DIRECTION,
      direction
    });
    

    Redux Reducer:

    import {
        GET_APP_LAYOUT_DIRECTION,
        SET_APP_LAYOUT_DIRECTION,
    } from '../actions/app';
    
    const initialState = {
        layout: 'ltr',
    };
    
    const reducer = (state = initialState, action) => {
        switch (action.type) {
          case GET_APP_LAYOUT_DIRECTION:
            return {
              ...state,
            };
          case SET_APP_LAYOUT_DIRECTION:
            return {
              ...state,
              layout: action.direction,
            };
          default:
            return state;
        }
    };
    
    export default reducer;
    

    Home Screen:

    import PropTypes from 'prop-types';
    import { connect } from 'react-redux';
    import RNRestart from 'react-native-restart'; // Import package from node modules
    import { getAppLayoutDirection, setAppLayoutDirection } from '../actions/app';
    
    class Home extends PureComponent {
       constructor(props) {
         super(props);
    
         this.props.dispatch(getAppLayoutDirection());
         if(this.props.layout === 'ltr'){
           this.props.dispatch(setAppLayoutDirection('rtl'));
           RNRestart.Restart();
         }
      }
    
      componentDidMount() {
         if(this.props.layout && this.props.layout === 'rtl'){
            SplashScreen.hide();
         }
      }
    } 
    
    const mapStateToProps = (state) => {
      const { layout } = state.app;
      return {
        layout
      };
    }
    
    export default connect(mapStateToProps)(Home);
    
    0 讨论(0)
提交回复
热议问题