Есть ли способ легко определить, является ли язык, на котором установлено устройство, справа налево (RTL)?
IOS: Определите, является ли язык устройства справа налево (RTL)
Ответ 1
В iOS 9 можно определить направление тока для каждого отдельного вида.
if #available(iOS 9.0, *) {
if UIView.userInterfaceLayoutDirection(
for: myView.semanticContentAttribute) == .rightToLeft {
// The view is shown in right-to-left mode right now.
}
} else {
// Use the previous technique
if UIApplication.shared.userInterfaceLayoutDirection == .rightToLeft {
// The app is in right-to-left mode
}
}
Это рекомендуемый способ определения направления макета в iOS 9.
WWDC 2015 video Новая поддержка UIKit для международных пользовательских интерфейсов. Через минуту 31:20.
Ответ 2
Существует официальный способ сделать это:
if ([UIApplication sharedApplication].userInterfaceLayoutDirection == UIUserInterfaceLayoutDirectionRightToLeft) {
}
Я бы рекомендовал не использовать некоторые другие решения, потому что они не всегда вернут правильный язык. Просто потому, что он на вершине предпочтительных языков не означает, что приложение поддерживает его.
Ответ 3
NSLocale
имеет два метода +characterDirectionForLanguage:
и +lineDirectionForLanguage:
. Первый, предположительно, слева направо и справа налево, а второй - "сверху вниз" и "снизу вверх". Вы можете передать ему результат [[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode]
.
Update:
Первоначальный вопрос: как определить, является ли язык устройства RTL. Использование +[NSLocale characterDirectionForLanguage:]
и +[NSLocale lineDirectionForLanguage:]
однозначно корректно для этого; вы можете передать либо [[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode]
, либо [NSLocale preferredLanguages][0]
, чтобы получить соответствующую информацию (я не уверен в том, что NSLocaleLanguageCode
использует предпочтительный язык или заданную область).
Однако очень вероятно, что то, что действительно хотел знать оригинальный плакат, заключается в том, должен ли интерфейс приложения располагаться в RTL или LTR. Это очень похоже на вопрос о том, каково направление языка, за исключением того, что он учитывает доступные локализации приложения. Если приложение не локализовано на предпочтительном для пользователя языке, оно будет использовать вместо него предпочтительный язык. И ответ на этот вопрос заключается в использовании [UIApplication sharedApplication].userInterfaceLayoutDirection
.
Ответ 4
Убедитесь, что вы вернули выбранный язык, а не текущую область устройства. Регион и язык часто совпадают. Однако, если я нахожусь в Северной Америке, и я задал свой язык японскому языку, мой регион по-прежнему будет английский (Соединенные Штаты). Чтобы проверить направление символа текущего выбранного языка, вы можете сделать:
+ (BOOL)isDeviceLanguageRTL {
return ([NSLocale characterDirectionForLanguage:[[NSLocale preferredLanguages] objectAtIndex:0]] == NSLocaleLanguageDirectionRightToLeft);
}
Возможно, вам захочется кэшировать результат, используя dispatch_once
.
Имейте в виду, что это предпочтительное языковое направление пользователя, а не обязательно языковое направление текста. Для этого используйте функцию C, основанную на u_charDirection
.
Ответ 5
Благодаря ответу Кевина Балларда мне удалось создать следующую служебную функцию:
+ (BOOL)isDeviceLanguageRTL {
return [NSLocale characterDirectionForLanguage:[[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode]]==NSLocaleLanguageDirectionRightToLeft;
}
Ответ 6
Вот быстрая версия 3:
import UIKit
extension UIView
{
/// Returns text and UI direction based on current view settings
var userInterfaceLayoutDirection: UIUserInterfaceLayoutDirection
{
if #available(iOS 9.0, *) {
return UIView.userInterfaceLayoutDirection(for: self.semanticContentAttribute)
} else {
return UIApplication.shared.userInterfaceLayoutDirection
}
}
}
Ответ 7
Вот как я использовал его:
+(NSTextAlignment) alignmentOfLanguage {
if ([NSLocale characterDirectionForLanguage:[[NSLocale preferredLanguages] objectAtIndex:0]]==NSLocaleLanguageDirectionRightToLeft){
return NSTextAlignmentRight;
}
return NSTextAlignmentLeft;
}
Последний пример не работал у меня, но с небольшим вариантом я получил его rightX2.
любые комментарии?
Ответ 8
Хорошо, хотя это старый вопрос с принятым ответом, я все равно отвечу.
Для тех, кто хочет проверить, является ли язык устройства RTL независимым, если ваше приложение поддерживает или не поддерживает этот язык, вы должны использовать [NSLocale characterDirectionForLanguage:]
следующим образом:
+ (BOOL)isDeviceLanguageRightToLeft {
NSLocale *currentLocale = [NSLocale currentLocale];
NSLocaleLanguageDirection direction = [NSLocale characterDirectionForLanguage:[currentLocale objectForKey:NSLocaleLanguageCode]];
return (direction == NSLocaleLanguageDirectionRightToLeft);
}
Приведенный выше код вернет YES
, если ваше приложение поддерживает только английский язык, но ваше устройство, например, установлено на арабский.
Apple рекомендует использовать [UIApplication sharedApplication].userInterfaceLayoutDirection
только потому, что возвращает направление, основанное на языке, используемом вашим приложением (имеет поддержку). Вот фрагмент кода:
+ (BOOL)isAppLanguageRightToLeft {
NSLocaleLanguageDirection direction = [UIApplication sharedApplication].userInterfaceLayoutDirection;
return (direction == UIUserInterfaceLayoutDirectionRightToLeft);
}
Приведенный выше код вернет NO
, когда ваше приложение поддерживает только английский язык, но ваше устройство установлено на арабский, например.
Ответ 9
Роуз Перроне совершенно верна. Однако использование dispatch_once в getter для простого логического значения - на самом деле слишком много накладных расходов. Ненужное использование отправки один раз. Поскольку вы, вероятно, захотите использовать это много раз в макете или функции рисования.
Итак, у вас есть два более быстрых варианта:
+ (BOOL)isRtl
{
static BOOL isRtl = NO;
static BOOL isRtlFound = NO;
if (!isRtlFound)
{ // This is "safe enough". Worst case is this code will be called twice in the app lifecycle...
isRtl = [NSLocale characterDirectionForLanguage:[NSBundle mainBundle].preferredLocalizations[0]] == NSLocaleLanguageDirectionRightToLeft;
isRtlFound = YES;
}
return isRtl;
}
Или просто кешируйте его в статической переменной, используя статический конструктор:
static BOOL s_isRtl = NO;
+ initialize
{
s_isRtl = [NSLocale characterDirectionForLanguage:[NSBundle mainBundle].preferredLocalizations[0]] == NSLocaleLanguageDirectionRightToLeft;
}
Обратите внимание, что это фактически будет передавать статическую переменную между любым классом, использующим этот код.
Ответ 10
if ([[UIDevice currentDevice].systemVersion floatValue] >= 9.0) {
if ([UIView userInterfaceLayoutDirectionForSemanticContentAttribute:self.view.semanticContentAttribute] == UIUserInterfaceLayoutDirectionRightToLeft) {
NSLog(@"Right to left");
}
else{
NSLog(@"left to Right");
}
} else {
/* Use the previous technique */
//Work for earlier ios 6 to ios 10
if ([NSLocale characterDirectionForLanguage:[[NSLocale preferredLanguages] objectAtIndex:0]] == NSLocaleLanguageDirectionRightToLeft) {
NSLog(@"Right to left");
}
else{
NSLog(@"left to Right");
}
}
должен смотреть Дополнительные темы в интернационализации wwdc2014
Ответ 11
если вы хотите проверить, работает ли устройство в RTL или LTR в режиме быстрого 3
if(UIApplication.shared.userInterfaceLayoutDirection == UIUserInterfaceLayoutDirection.rightToLeft) {
//RTL
} else {
//LTR
}