Подтвердить что ты не робот

IOS: Определите, является ли язык устройства справа налево (RTL)

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

4b9b3361

Ответ 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) {
}

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

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

Ответ 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
}