Вопрос по ios, localization – iOS: определите, является ли язык устройства справа налево (RTL)

33

Есть ли способ легко определить, является ли язык, на котором установлено устройство, справа налево (RTL)?

Ваш Ответ

11   ответов
4

Благодаря ответу Кевина Балларда я смог создать для этого следующую служебную функцию:

+ (BOOL)isDeviceLanguageRTL {
   return [NSLocale characterDirectionForLanguage:[[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode]]==NSLocaleLanguageDirectionRightToLeft;
}
Хотя ответ @ Accatyyc является технически правильным, в моем случае он не вернул правильное значение. Я тестирую на iOS8, меняю язык на арабский, но методuserInterfaceLayoutDirection вернул LTR. Поэтому я попробовал этот ответ, и он решил мою проблему.
1

если вы хотите проверить, работает ли устройство в RTL или LTR в Swift 3

if(UIApplication.shared.userInterfaceLayoutDirection == UIUserInterfaceLayoutDirection.rightToLeft) {
    //RTL
} else {
   //LTR
}
17

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.

@wakachamo: Пожалуйста, прекратите редактировать мой ответ.
@KevinBallard Оригинальный вопрос о системном языке, на котором работает устройство.[NSLocale preferredLanguages][0] может быть языком, на котором устройство не установлено, так что, к сожалению, это приведет к неточным результатам.
@wakachamo: Вопрос, который был задан, определял, является ли язык RTL.[UIApplication sharedApplication].userInterfaceLayoutDirection объявляет, должно ли быть указано направление интерфейса LTR или RTL. Это не совсем то, что задавал вопрос. Хотя на самом деле это может быть тем, чего хотел оригинальный плакат.
К сожалению это неверно; лучший способ сделать это через[UIApplication sharedApplication].userInterfaceLayoutDirectionкак уже упоминалось вanswer below.
Вниз голосование этого ответа. Посмотри пожалуйстаwakachamoкомментарий о лучшем способе определения направления компоновки интерфейса.
1
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

48

В 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Новая поддержка UIKit для международных пользовательских интерфейсов, После минуты 31:20.

Можно ли в любом случае пометить ответ как "правильный сейчас"? Для потомков ответ, который я выбрал три года назад, был правильным в то время, но, вероятно, он должен быть выше. BarrettJ
@BarrettJ вы всегда можете отказаться и принять другой ответ.
Я получаю сообщение об ошибке "Тип UIView не имеет члена userInterfaceLayoutDirection" при использовании Xcode 7.3, swift 2.2 и для iOS 9
СейчасUIView.userInterfaceLayoutDirectionForSemanticContentAttribute(semanticContentAttribute) == .RightToLeft.
Можете ли вы объяснить, техника предыдущих версий для IOS 8
1

Хорошо, хотя это старый вопрос с принятым ответом, я все равно отвечу на него.

Для тех, кто хочет проверить,the device language is 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 когда ваше приложение поддерживает только английский, но ваше устройство, например, настроено на арабский.

0

Роза Перроне совершенно права. Однако использование dispatch_once в геттере для простого логического значения - действительно слишком много накладных расходов. Ненужное использование рассылки один раз. Потому что вы, вероятно, захотите использовать это много раз внутри макета или функции рисования.

Таким образом, у вас есть два более быстрых варианта:

+ (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's 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;
}

Обратите внимание, что это фактически разделит статическую переменную между всеми классами, которые используют этот код.

dispatch_once refresher: & quot; Эта функция полезна для инициализации глобальных данных (синглетонов) в приложении. Всегда вызывайте эту функцию перед использованием или тестированием любых переменных, которые инициализируются блоком. Если эта функция вызывается одновременно из нескольких потоков, она ожидает синхронно до завершения блока. Предикат должен указывать на переменную, хранящуюся в глобальной или статической области видимости. & Quot;
39

Есть официальный способ сделать это:

if ([UIApplication sharedApplication].userInterfaceLayoutDirection == UIUserInterfaceLayoutDirectionRightToLeft) {
}

Я бы рекомендовал не использовать некоторые другие решения, потому что они не всегда будут возвращать правильную локаль. Тот факт, что он находится на вершине предпочтительных языков, не означает, что приложение поддерживает его.

Источник:https://developer.apple.com/library/content/documentation/MacOSX/Conceptual/BPInternational/SupportingRight-To-LeftLanguages/SupportingRight-To-LeftLanguages.html

Это (учитывая неясный смысл вопроса ФП), скорее всего, того, что хотел ФП.
Пожалуйста, обратите внимание, что Apple обновила свои документы, и теперь рекомендует другой метод - только iOS 9. Увидеть:stackoverflow.com/a/31759275/785716
Я использую это в некоторых случаях, даже на iOS 9, так как иногда у вас просто нет экземпляра UIView для проверки атрибута semanticContentAttribute.
1

Вот как я это использовал:

+(NSTextAlignment) alignmentOfLanguage {
if ([NSLocale characterDirectionForLanguage:[[NSLocale preferredLanguages] objectAtIndex:0]]==NSLocaleLanguageDirectionRightToLeft){
        return NSTextAlignmentRight;
    }
   return NSTextAlignmentLeft;  
}

Последний пример не сработал для меня, но с небольшим вариантом я понял правильно X2.

любые комментарии?

10

Убедитесь, что вы возвращаете текущий выбранный язык, а не текущий регион устройства. Регион и язык часто совпадают. Однако, если я нахожусь в Северной Америке и установил свой язык на японский, моим регионом все равно будет английский (США). Чтобы проверить направление символов выбранного в данный момент языка, вы можете сделать:

+ (BOOL)isDeviceLanguageRTL {
  return ([NSLocale characterDirectionForLanguage:[[NSLocale preferredLanguages] objectAtIndex:0]] == NSLocaleLanguageDirectionRightToLeft);
}

Возможно, вы захотите кэшировать результат, используяdispatch_once.

Имейте в виду, что это предпочтительное направление языка пользователя, а не обязательно направление языка текста. Для этого используйте функцию C, основанную наu_charDirection.

Этот ответ тоже неверен - см. Мой ответ.
5

Вот быстрая 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
        }
    }
}

Похожие вопросы