67

Is there a way to easily determine if the language the device is set to is right to left (RTL)?

pasawaya
  • 11,515
  • 7
  • 53
  • 92
BarrettJ
  • 3,431
  • 2
  • 29
  • 26

15 Answers15

93

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.

Evgenii
  • 36,389
  • 27
  • 134
  • 170
  • 1
    Is there anyway to mark an answer as "correct now"? For posterity, the answer I chose three years ago was correct at the time, but this should probably be higher up. – BarrettJ Sep 17 '15 at 15:17
  • @BarrettJ you can always unaccept and accept another answer. – Tobi Nary Feb 01 '16 at 10:35
  • 2
    It's now `UIView.userInterfaceLayoutDirectionForSemanticContentAttribute(semanticContentAttribute) == .RightToLeft`. – Chrissi Jul 14 '16 at 10:26
  • I get an error 'Type UIView has no member userInterfaceLayoutDirection' when using Xcode 7.3, swift 2.2 and for iOS 9 – Zvi Sep 19 '16 at 20:35
  • can you please explain the previos technique for ios 8 – Muthu Selvam Mar 23 '17 at 05:53
  • In Xcode 10.2, setting the Simulator to Saudi Arabia and Arabic (which changes the UI to R-to-L), this call doesn't return .rightToLeft. – Rick Apr 22 '19 at 13:57
49

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.

Source: https://developer.apple.com/library/content/documentation/MacOSX/Conceptual/BPInternational/SupportingRight-To-LeftLanguages/SupportingRight-To-LeftLanguages.html

Cœur
  • 37,241
  • 25
  • 195
  • 267
Accatyyc
  • 5,798
  • 4
  • 36
  • 51
  • This is (given the unclear sense of the OP's question) most likely what the OP wanted. – Sean Mar 20 '15 at 22:56
  • Please note that Apple has updated their docs, and it now recommends a different method that is iOS 9 only. See: http://stackoverflow.com/a/31759275/785716 – Keab42 Oct 26 '15 at 12:35
  • I use this in certain cases, even on iOS 9, as sometimes you simply don't have an instance of a UIView to check the semanticContentAttribute against. – Mike Sep 22 '16 at 15:25
  • This won't work if your code belong in a framework or extension where UIAppiication is not available. – Herno Jul 11 '19 at 05:20
20

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.

Lily Ballard
  • 182,031
  • 33
  • 381
  • 347
  • 4
    Unfortunately this is incorrect; the best way to do it is through ```[UIApplication sharedApplication].userInterfaceLayoutDirection```, as mentioned in the [answer below](http://stackoverflow.com/a/25500099/242849). – wakachamo Mar 18 '15 at 22:24
  • 1
    Down-voting this answer. Please see `wakachamo`'s comment for the best way of determining the interface layout direction. – Sean Mar 18 '15 at 23:14
  • 4
    @wakachamo: The question that was asked was determining whether the language is RTL. `[UIApplication sharedApplication].userInterfaceLayoutDirection` declares whether the interface direction should be laid out LTR or RTL. This is not quite the same thing that the question was asking. Although it may in fact be what the original poster wanted. – Lily Ballard Mar 18 '15 at 23:25
  • 1
    @KevinBallard The original question asks about the system language the device is running in. ```[NSLocale preferredLanguages][0]``` can be a language that the device is not set to, so this will unfortunately lead to inaccurate results. – wakachamo Mar 19 '15 at 00:31
11

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.

Rose Perrone
  • 61,572
  • 58
  • 208
  • 243
6

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
        }
    }
}
David Rysanek
  • 901
  • 12
  • 16
6

If you just want to know a specific views layout direction on iOS 10+ you can use:

view.effectiveUserInterfaceLayoutDirection == .rightToLeft
Declan McKenna
  • 4,321
  • 6
  • 54
  • 72
  • In my opinion, this method is more effective than checking the language code from Locale.preferredLanguage list. Thanks buddy – Vivek Nov 07 '22 at 12:31
5

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;
}
Brad Larson
  • 170,088
  • 45
  • 397
  • 571
Gerhat
  • 823
  • 1
  • 10
  • 14
  • Although @Accatyyc's answer is technically correct, it did not return the correct value in my case. I test on iOS8, change language to arabic but the method `userInterfaceLayoutDirection` returned LTR. So I tried this answer and it resolved my problem. – FormigaNinja May 13 '15 at 09:05
3

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?

Y.Z.
  • 39
  • 1
3

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
}
Axel Guilmin
  • 11,454
  • 9
  • 54
  • 64
Tarek hemdan
  • 874
  • 2
  • 10
  • 24
1

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.

FormigaNinja
  • 1,571
  • 1
  • 24
  • 36
1
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

Ravi Kumar
  • 1,356
  • 14
  • 22
1

For iOS 9 and above



extension UIView {

    var isLayoutDirectionRightToLeft: Bool {
        UIView.userInterfaceLayoutDirection(for: semanticContentAttribute) == .rightToLeft
    }
    
}

    
Siempay
  • 876
  • 1
  • 11
  • 32
0

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.

daniel.gindi
  • 3,457
  • 1
  • 30
  • 36
  • dispatch_once refresher: "This function is useful for initialization of global data (singletons) in an application. Always call this function before using or testing any variables that are initialized by the block. If called simultaneously from multiple threads, this function waits synchronously until the block has completed. The predicate must point to a variable stored in global or static scope." – Ken Nov 15 '13 at 21:19
0

you can check RTL like this

- (BOOL)isDeviceLanguageRTL {
  return ([NSLocale characterDirectionForLanguage:[[NSLocale preferredLanguages] objectAtIndex:0]] == NSLocaleLanguageDirectionRightToLeft);
}
if ([self isDeviceLanguageRTL]) {
    //RTL
}
 else
{
   //LRT
}
Muhammad Numan
  • 23,222
  • 6
  • 63
  • 80
0

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")
}
Tamás Sengel
  • 55,884
  • 29
  • 169
  • 223