有没有办法轻松确定设备设置的语言是否是从右到左 (RTL)?
15 回答
在 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 视频New UIKit Support for International User Interfaces。31:20 分后。
有一个官方的方法来做到这一点:
if ([UIApplication sharedApplication].userInterfaceLayoutDirection == UIUserInterfaceLayoutDirectionRightToLeft) {
}
我建议不要使用其他一些解决方案,因为它们不会总是返回正确的语言环境。仅仅因为它在首选语言之上并不意味着应用程序支持它。
NSLocale
有两种方法+characterDirectionForLanguage:
和+lineDirectionForLanguage:
。第一个大概是从左到右 vs 从右到左,第二个是从上到下 vs 从下到上。你可以通过它的结果[[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode]
。
更新:
最初的问题是如何确定设备语言是否为 RTL。使用+[NSLocale characterDirectionForLanguage:]
and+[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
.
请记住,这是用户的首选语言方向,不一定是文本的语言方向。为此,请使用基于u_charDirection
.
这是一个 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
}
}
}
感谢 Kevin Ballard 的回答,我能够创建以下实用函数来执行此操作:
+ (BOOL)isDeviceLanguageRTL {
return [NSLocale characterDirectionForLanguage:[[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode]]==NSLocaleLanguageDirectionRightToLeft;
}
如果您只想知道 iOS 10+ 上的特定视图布局方向,可以使用:
view.effectiveUserInterfaceLayoutDirection == .rightToLeft
这是我使用它的方式:
+(NSTextAlignment) alignmentOfLanguage {
if ([NSLocale characterDirectionForLanguage:[[NSLocale preferredLanguages] objectAtIndex:0]]==NSLocaleLanguageDirectionRightToLeft){
return NSTextAlignmentRight;
}
return NSTextAlignmentLeft;
}
最后一个例子对我不起作用,但有一个小变种,我得到了正确的 X2。
任何意见?
如果您想在 swift 3 中检查设备是在 RTL 还是 LTR 中运行
if(UIApplication.shared.userInterfaceLayoutDirection == UIUserInterfaceLayoutDirection.rightToLeft) {
//RTL
} else {
//LTR
}
好的,虽然这是一个可以接受答案的老问题,但无论如何我都会回答。
对于那些想要检查设备语言是否为 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
当您的应用仅支持英语但您的设备设置为阿拉伯语时,上述代码将返回。
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");
}
}
Rose Perrone 是完全正确的。然而,在一个简单的布尔值的 getter 中使用 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;
}
请注意,这实际上将在使用此代码的任何类之间共享静态变量。
适用于 iOS 9 及更高版本
extension UIView {
var isLayoutDirectionRightToLeft: Bool {
UIView.userInterfaceLayoutDirection(for: semanticContentAttribute) == .rightToLeft
}
}
你可以像这样检查RTL
- (BOOL)isDeviceLanguageRTL {
return ([NSLocale characterDirectionForLanguage:[[NSLocale preferredLanguages] objectAtIndex:0]] == NSLocaleLanguageDirectionRightToLeft);
}
if ([self isDeviceLanguageRTL]) {
//RTL
}
else
{
//LRT
}
在 macOS 上,NSView 有一个userInterfaceLayoutDirection
属性可以用来确定语言方向。归功于iOS版本的这个答案。
let view = NSView()
if view.userInterfaceLayoutDirection == .rightToLeft {
print("RTL")
}