Is there a way to easily determine if the language the device is set to is right to left (RTL)?
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.
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");
}
}
must watch Advanced Topics in Internationalization wwdc2014
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
}
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.
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;
}