iOS:确定设备语言是否为从右向左(RTL)

iOS:确定设备语言是否为从右向左(RTL),ios,localization,Ios,Localization,是否有一种方法可以轻松确定设备设置的语言是否为从右向左(RTL)?NSLocale有两种方法+characterDirectionForLanguage:和+lineDirectionForLanguage:。第一种可能是从左到右vs从右到左,第二种可能是从上到下vs从下到上。您可以将[[NSLocale currentLocale]objectForKey:NSLocaleLanguageCode]的结果传递给它 更新: 最初的问题是如何确定设备语言是否为RTL。使用+[NSLocale ch

是否有一种方法可以轻松确定设备设置的语言是否为从右向左(RTL)?

NSLocale
有两种方法
+characterDirectionForLanguage:
+lineDirectionForLanguage:
。第一种可能是从左到右vs从右到左,第二种可能是从上到下vs从下到上。您可以将
[[NSLocale currentLocale]objectForKey:NSLocaleLanguageCode]
的结果传递给它

更新:

最初的问题是如何确定设备语言是否为RTL。使用
+[NSLocale characterDirectionForLanguage:
+[NSLocale lineDirectionForLanguage:
显然是正确的;您可以将
[[NSLocale currentLocale]objectForKey:NSLocaleLanguageCode]
[NSLocale preferredLanguages][0]
传递给该对象以获取相关信息(我不确定
NSLocaleLanguageCode
是使用首选语言还是使用设置区域)


然而,很可能原始海报真正想知道的是应用程序的接口是否应该用RTL或LTR进行布局。这与询问语言的方向非常相似,只是它考虑了应用程序的可用本地化。如果应用程序未本地化为用户的首选语言,它将使用非首选语言。这个问题的答案是使用
[UIApplication sharedApplication].userInterfaceLayoutDirection

由于Kevin Ballard的回答,我能够创建以下实用程序函数来实现这一点:

+ (BOOL)isDeviceLanguageRTL {
   return [NSLocale characterDirectionForLanguage:[[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode]]==NSLocaleLanguageDirectionRightToLeft;
}

确保返回当前选定的语言,而不是设备的当前区域。地区和语言通常是相同的。然而,如果我在北美,并且我将我的语言设置为日语,我所在的地区仍然是英语(美国)。要检查当前选定语言的字符方向,可以执行以下操作:

+ (BOOL)isDeviceLanguageRTL {
  return ([NSLocale characterDirectionForLanguage:[[NSLocale preferredLanguages] objectAtIndex:0]] == NSLocaleLanguageDirectionRightToLeft);
}
您可能希望使用
dispatch\u once
缓存结果


请记住,这是用户首选的语言方向,而不一定是文本的语言方向。为此,请使用基于
u\u charDirection
的C函数。Rose Perrone是完全正确的。然而,在一个getter中对一个简单的布尔值使用dispatch_一次,确实是太多的开销。不必要地使用调度一次。 因为您可能希望在布局或绘图功能中使用多次

因此,您有两个更快的选择:

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

请注意,这实际上将在使用此代码的任何类之间共享静态变量。

以下是我如何使用它的:

+(NSTextAlignment) alignmentOfLanguage {
if ([NSLocale characterDirectionForLanguage:[[NSLocale preferredLanguages] objectAtIndex:0]]==NSLocaleLanguageDirectionRightToLeft){
        return NSTextAlignmentRight;
    }
   return NSTextAlignmentLeft;  
}
最后一个例子对我不起作用,但通过一个小小的变化,我得到了正确的答案


有什么意见吗?

有一种官方的方法:

if ([UIApplication sharedApplication].userInterfaceLayoutDirection == UIUserInterfaceLayoutDirectionRightToLeft) {
}
我建议不要使用其他一些解决方案,因为它们并不总是返回正确的区域设置。仅仅因为它位于首选语言之上并不意味着应用程序支持它


来源:

好的,虽然这是一个老问题,有一个公认的答案,但我还是会回答的

对于希望检查设备语言是否为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

在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视频。31:20分后

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");
    }
}

必须观看

以下是swift 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
        }
    }
}

如果要检查设备是否在swift 3的RTL或LTR中运行

if(UIApplication.shared.userInterfaceLayoutDirection == UIUserInterfaceLayoutDirection.rightToLeft) {
    //RTL
} else {
   //LTR
}
适用于iOS 9及以上版本


扩展UIView{
变量isLayoutDirectionRightToLeft:Bool{
UIView.userInterfaceLayoutDirection(for:semanticContentAttribute)=.rightToLeft
}
}

如果您只想知道iOS 10+上的特定视图布局方向,可以使用:

view.effectiveUserInterfaceLayoutDirection == .rightToLeft

你可以像这样检查RTL

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

dispatch_once refresher:“此函数用于初始化全局数据(单例数据)在应用程序中。在使用或测试由块初始化的任何变量之前,始终调用此函数。如果从多个线程同时调用,此函数将同步等待,直到块完成。谓词必须指向存储在全局或静态范围中的变量。“不幸的是,这是不正确的;最好的方法是通过
[UIApplication sharedApplication].userInterfaceLayoutDirection
,如此答案的.Down投票中所述。有关确定接口布局方向的最佳方法,请参见
wakachamo
的评论。@wakachamo:所问的问题是确定语言是否为RTL<代码>[UIApplication sharedApplication].userInterfaceLayoutDirection声明接口方向是LTR还是RTL。这与问题所问的不完全相同。“虽然它实际上可能是原始海报想要的东西。”KevinBallard原始问题询问设备运行的系统语言<代码>[NSLocale preferredLanguages][0]可以是
if ([self isDeviceLanguageRTL]) {
    //RTL
}
 else
{
   //LRT
}