skip to Main Content

Android is responding well to direction change, however iOS isn’t switching RTL correctly, iOS keep restarting and when I checked the state of isRTL is doesn’t change

 useEffect(() => {
    initializingSet(true);
    const languageSetter = async () => {
      const storageLang = await AsyncStorage.getItem("appLang");
      const systemLanguage = getLocales()[0].languageCode;
      const { isRTL } = I18nManager;
      console.log(
        storageLang,
        storageLang,
        appLang,
        I18nManager.isRTL,
        "<<=Lang"
      );
      if (appLang) {
        changeLanguage(appLang);
        if (appLang !== storageLang) {
          AsyncStorage.setItem("appLang", appLang);
        }
        if ((appLang === "en" && isRTL) || (appLang !== "en" && !isRTL)) {
          I18nManager.allowRTL(!isRTL);
          I18nManager.forceRTL(!isRTL); // FIXNOW: iOS not switching to RTL
          RNRestart.restart();
        }
        initializingSet(false);
      } else {
        if (storageLang) {
          appLangSet(storageLang as AppLanguagesType);
        } else {
          if (systemLanguage) {
            AsyncStorage.setItem("appLang", systemLanguage).finally(() =>
              appLangSet(systemLanguage as AppLanguagesType)
            );
          } else {
            appLangSet("en");
          }
        }
      }
    };

    languageSetter();
  }, [appLang]);

my app.json has the supportsRTL

   "extra": {
      "supportsRTL": true,
           }

The same app run on Android just fine!
Any thoughts?

3

Answers


  1. Chosen as BEST ANSWER

    After alot of search I found this issue https://github.com/expo/expo/issues/26532

    removing expo-localization fixed it, now I am using native modules to detect language

    const systemLanguage = (
            (Platform.OS === "ios"
              ? NativeModules.SettingsManager.settings.AppleLocale ||
                NativeModules.SettingsManager.settings.AppleLanguages[0] //iOS 13
              : NativeModules.I18nManager.localeIdentifier) as string | undefined
          )?.substring(0, 2) as AppLanguagesType | undefined;
    

  2. I recommend you to add it in AppDelegate.mm on iOS project.

    #import <React/RCTI18nUtil.h>
    ...
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
    ...
     [[RCTI18nUtil sharedInstance] allowRTL:YES];
    ...
    }
    
    Login or Signup to reply.
  3. I think you are missing i18n in this line: changeLanguage(appLang)

    Replace it something like this: i18n.changeLanguage('ar')

    Example My Language Switching Tabs:

    import React from 'react';
    import {Text, View, Pressable, I18nManager} from 'react-native';
    import {useDispatch, useSelector} from 'react-redux';
    import {useTranslation} from 'react-i18next';
    import {useInjectReducer} from 'redux-injectors';
    import RNRestart from 'react-native-restart';
    
    import {GlobalSelector} from '../../store/selector';
    import globalReducer, {setLanguage} from '../../store/global';
    import {SaveLanguage} from '../../utils/languageStorage';
    import LanguageTabStyle from './style';
    import AppColor from '../../constants/Colors';
    
    const LanguageTabs = ({containerStyle}) => {
      const {t, i18n} = useTranslation();
      const {BLACK} = AppColor();
    
      useInjectReducer({key: 'global', reducer: globalReducer});
    
      const dispatch = useDispatch();
      const {language} = useSelector(GlobalSelector);
      const styles = LanguageTabStyle();
    
      return (
        <View style={[styles.mainContainer, {...containerStyle}]}>
          <Pressable
            onPress={async () => {
              i18n.changeLanguage('en');
              dispatch(setLanguage('English'));
              if (I18nManager.isRTL) {
                await I18nManager.forceRTL(false);
                await SaveLanguage('English');
                RNRestart.Restart();
              }
            }}
            style={
              language === 'English' ? styles.activeButton : styles.inActiveButton
            }>
            <Text style={[styles.text, {color: BLACK}]}>{t('English')}</Text>
          </Pressable>
          <Pressable
            onPress={async () => {
              i18n.changeLanguage('ar');
              dispatch(setLanguage('Arabic'));
              await SaveLanguage('Arabic');
              if (!I18nManager.isRTL) {
                await I18nManager.forceRTL(true);
                await SaveLanguage('Arabic');
                RNRestart.Restart();
              }
            }}
            style={
              language === 'Arabic' ? styles.activeButton : styles.inActiveButton
            }>
            <Text style={[styles.text, {color: BLACK}]}>{t('Arabic')}</Text>
          </Pressable>
        </View>
      );
    };
    
    export default LanguageTabs;
    
    

    Hopefully it will help you.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search