Android хорошо реагирует на изменение направления, однако iOS не переключает RTL правильно, iOS продолжает перезагружаться, и когда я проверил, состояние isRTL не меняется.
useEffect(() => {
initializingSet(true);
const languageSetter = async () => {
const storageLang = await AsyncStorage.getItem("appLang");
const systemLanguage = getLocales()[0].languageCode;
const { isRTL } = I18nManager;
console.info(
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]);
в моем app.json есть supportsRTL
"extra": {
"supportsRTL": true,
}
Это же приложение отлично работает на Android! Есть предположения?





Я рекомендую вам добавить его в AppDelegate.mm в проекте iOS.
#import <React/RCTI18nUtil.h>
...
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
...
[[RCTI18nUtil sharedInstance] allowRTL:YES];
...
}
если вам нужен режим RTL,allowRTL:YES илиallowRTL:NO.
Мне кажется, вам не хватает i18n в этой строке: changeLanguage(appLang)
Замените его примерно так: i18n.changeLanguage('ar')
Пример вкладок переключения моего языка:
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;
У меня есть changeLanguage(appLang);, который вызывает библиотеку i18n.
После долгих поисков я нашел эту проблему https://github.com/expo/expo/issues/26532
удаление expo-localization исправило, теперь я использую собственные модули для определения языка
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;
К сожалению, не решил мою проблему