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

有没有方法可以轻松确定设备的语言是否是从右到左(RTL)?

在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 2015video新UIKit支持国际用户界面 。 31:20分钟后。

有一个正式的方法来做到这一点:

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

我build议不要使用其他一些解决scheme,因为它们不会总是返回正确的语言环境。 只是因为它在首选语言的顶部并不意味着应用程序支持它。

资料来源: https : //developer.apple.com/library/content/documentation/MacOSX/Conceptual/BPInternational/SupportingRight-To-LeftLanguages/SupportingRight-To-LeftLanguages.html

NSLocale有两个方法+characterDirectionForLanguage:+lineDirectionForLanguage: 第一个可能是从左到右与从右到左,第二个是从上到下与从下到上。 你可以传递它[[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode]

更新:

原来的问题是如何确定设备语言是否为RTL。 使用+[NSLocale characterDirectionForLanguage:]+[NSLocale lineDirectionForLanguage:]是明确正确的; 你可以传递[[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode][NSLocale preferredLanguages][0]来获取相关信息(我不确定NSLocaleLanguageCode使用首选语言还是设置区域)。

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

确保您返回当前选定的语言,而不是设备的当前区域。 地区和语言往往是相同的。 但是,如果我在北美,而且我的语言是日语,我的地区仍然是英语(美国)。 为了检查当前所选语言的字符方向,您可以执行:

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

您可能需要使用dispatch_once来caching结果。

请记住,这是用户首选的语言方向,而不一定是文本的语言方向。 为此,请使用基于u_charDirection的C函数。

感谢Kevin Ballard的回答,我能够创build以下实用程序function来执行此操作:

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

这里是一个快速的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 } } } 

这是我如何使用它:

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

最后一个例子对我来说不起作用,但是有了一个小变种,我知道了X2。

任何意见?

好吧,虽然这是一个接受答案的老问题,我仍然会回答。

对于那些想要检查设备语言是否为RTL的用户 ,如果你的应用程序支持或不支持这种语言,你应该使用[NSLocale characterDirectionForLanguage:]像这样:

 + (BOOL)isDeviceLanguageRightToLeft { NSLocale *currentLocale = [NSLocale currentLocale]; NSLocaleLanguageDirection direction = [NSLocale characterDirectionForLanguage:[currentLocale objectForKey:NSLocaleLanguageCode]]; return (direction == NSLocaleLanguageDirectionRightToLeft); } 

上面的代码将返回YES如果您的应用程序只支持英语,但您的设备设置为阿拉伯语为例。

Applebuild议您使用[UIApplication sharedApplication].userInterfaceLayoutDirection ,仅仅是因为它根据您的应用程序正在使用的语言(已经支持)返回方向。 这里是代码片段:

 + (BOOL)isAppLanguageRightToLeft { NSLocaleLanguageDirection direction = [UIApplication sharedApplication].userInterfaceLayoutDirection; return (direction == UIUserInterfaceLayoutDirectionRightToLeft); } 

上面的代码将返回NO时,您的应用程序只支持英语,但您的设备设置为阿拉伯语为例。

罗斯·佩罗内是完全正确的。 然而,在一个简单的布尔值getter中使用dispatch_once实际上是太多的开销。 不必要的使用调度一次。 因为您可能要在布局或绘图function中使用那么多次。

所以你有两个更快的select:

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

或者使用静态构造函数将它caching在一个静态variables中:

 static BOOL s_isRtl = NO; + initialize { s_isRtl = [NSLocale characterDirectionForLanguage:[NSBundle mainBundle].preferredLocalizations[0]] == NSLocaleLanguageDirectionRightToLeft; } 

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

 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

如果你想检查设备是否在RTL或LTR中快速运行3

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