iOS: Determine if device language is Right to Left (RTL)
IosLocalizationIos Problem Overview
Is there a way to easily determine if the language the device is set to is right to left (RTL)?
Ios Solutions
Solution 1 - Ios
In iOS 9 one can determine the current direction for each individual view.
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
}
}
This is the recommended way of determining the layout direction in iOS 9.
WWDC 2015 video New UIKit Support for International User Interfaces. After minute 31:20.
Solution 2 - Ios
There is an official way to do it:
if ([UIApplication sharedApplication].userInterfaceLayoutDirection == UIUserInterfaceLayoutDirectionRightToLeft) {
}
I would recommend against using some of the other solutions, because they will not always return the correct locale. Just because it's on the top of preferred languages doesn't mean that the application supports it.
Solution 3 - Ios
NSLocale
has two methods +characterDirectionForLanguage:
and +lineDirectionForLanguage:
. The first is presumably Left-to-Right vs Right-to-Left and the second is Top-to-Bottom vs Bottom-to-Top. You can pass it the result of [[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode]
.
Update:
The original question asked was how to determine whether the device language is RTL. Using +[NSLocale characterDirectionForLanguage:]
and +[NSLocale lineDirectionForLanguage:]
is unambiguously correct for that; you can pass either [[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode]
or [NSLocale preferredLanguages][0]
to that to get the relevant info (I'm not sure offhand whether the NSLocaleLanguageCode
uses the preferred language, or the set region).
However, it's very likely that what the original poster actually wanted to know is whether the application's interface should be laid out in RTL or LTR. This is very similar to asking what the direction of the language is, except it takes the application's available localizations into account. If the application is not localized into the user's preferred language, it will use a non-preferred language instead. And the answer to this question is to use [UIApplication sharedApplication].userInterfaceLayoutDirection
.
Solution 4 - Ios
Make sure you return the currently selected language, not the current region of the device. The region and language are often the same. However, if I am in North America and I set my language to Japanese, my region will still be English (United States). In order to check the character direction of the currently selected language, you can do:
+ (BOOL)isDeviceLanguageRTL {
return ([NSLocale characterDirectionForLanguage:[[NSLocale preferredLanguages] objectAtIndex:0]] == NSLocaleLanguageDirectionRightToLeft);
}
You may likely want to cache the result, using dispatch_once
.
Keep in mind that this is the user's preferred language direction, and not necessarily the language direction of the text. For that, use a C function that is based on u_charDirection
.
Solution 5 - Ios
Here is a swift 3 version:
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
}
}
}
Solution 6 - Ios
Thanks to Kevin Ballard's answer I was able to create the following utility function to do this:
+ (BOOL)isDeviceLanguageRTL {
return [NSLocale characterDirectionForLanguage:[[NSLocale currentLocale] objectForKey:NSLocaleLanguageCode]]==NSLocaleLanguageDirectionRightToLeft;
}
Solution 7 - Ios
If you just want to know a specific views layout direction on iOS 10+ you can use:
view.effectiveUserInterfaceLayoutDirection == .rightToLeft
Solution 8 - Ios
Here is how i Used it :
+(NSTextAlignment) alignmentOfLanguage {
if ([NSLocale characterDirectionForLanguage:[[NSLocale preferredLanguages] objectAtIndex:0]]==NSLocaleLanguageDirectionRightToLeft){
return NSTextAlignmentRight;
}
return NSTextAlignmentLeft;
}
The Last example didn't work for me , but with a little variant , i got it rightX2 .
any comments?
Solution 9 - Ios
if you want to check if the device is running in RTL or LTR in swift 3
if(UIApplication.shared.userInterfaceLayoutDirection == UIUserInterfaceLayoutDirection.rightToLeft) {
//RTL
} else {
//LTR
}
Solution 10 - Ios
Ok, although it's an old question with an accepted answer, I will answer it anyway.
For those who wants to check whether the device language is RTL, independent if your application supports or not this language, you should use [NSLocale characterDirectionForLanguage:]
like this:
+ (BOOL)isDeviceLanguageRightToLeft {
NSLocale *currentLocale = [NSLocale currentLocale];
NSLocaleLanguageDirection direction = [NSLocale characterDirectionForLanguage:[currentLocale objectForKey:NSLocaleLanguageCode]];
return (direction == NSLocaleLanguageDirectionRightToLeft);
}
The code above will return YES
if your app only supports english, but your device is set to Arabic for example.
Apple recommends that you use [UIApplication sharedApplication].userInterfaceLayoutDirection
, just because it returns the direction based on the language that your app is using (has support to). Here is the code snippet:
+ (BOOL)isAppLanguageRightToLeft {
NSLocaleLanguageDirection direction = [UIApplication sharedApplication].userInterfaceLayoutDirection;
return (direction == UIUserInterfaceLayoutDirectionRightToLeft);
}
The code above will return NO
when your app only supports english, but your device is set to Arabic for example.
Solution 11 - Ios
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");
}
}
Solution 12 - Ios
Rose Perrone is completely correct. However the use of dispatch_once in a getter for a simple boolean value - is really too much overhead. Unnecessary use of dispatch once. Because you will probably want to use that many times inside a layout or drawing function.
So you have two faster options:
+ (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;
}
Or just cache it in a static variable, using the static constructor:
static BOOL s_isRtl = NO;
+ initialize
{
s_isRtl = [NSLocale characterDirectionForLanguage:[NSBundle mainBundle].preferredLocalizations[0]] == NSLocaleLanguageDirectionRightToLeft;
}
Note that this will actually share the static variable between any class that uses this code.
Solution 13 - Ios
> For iOS 9 and above
extension UIView {
var isLayoutDirectionRightToLeft: Bool {
UIView.userInterfaceLayoutDirection(for: semanticContentAttribute) == .rightToLeft
}
}
Solution 14 - Ios
you can check RTL like this
- (BOOL)isDeviceLanguageRTL {
return ([NSLocale characterDirectionForLanguage:[[NSLocale preferredLanguages] objectAtIndex:0]] == NSLocaleLanguageDirectionRightToLeft);
}
if ([self isDeviceLanguageRTL]) {
//RTL
}
else
{
//LRT
}
Solution 15 - Ios
On macOS, NSView has a userInterfaceLayoutDirection
property you can use to determine the language direction. Credits to this answer for the iOS version.
let view = NSView()
if view.userInterfaceLayoutDirection == .rightToLeft {
print("RTL")
}