iOS: Determine if device language is Right to Left (RTL)

IosLocalization

Ios 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.

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

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");
    }
}

must watch Advanced Topics in Internationalization wwdc2014

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")
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBarrettJView Question on Stackoverflow
Solution 1 - IosEvgeniiView Answer on Stackoverflow
Solution 2 - IosAccatyycView Answer on Stackoverflow
Solution 3 - IosLily BallardView Answer on Stackoverflow
Solution 4 - IosRose PerroneView Answer on Stackoverflow
Solution 5 - IosDavid RysanekView Answer on Stackoverflow
Solution 6 - IosGerhatView Answer on Stackoverflow
Solution 7 - IosDeclan McKennaView Answer on Stackoverflow
Solution 8 - IosY.Z.View Answer on Stackoverflow
Solution 9 - IosTarek hemdanView Answer on Stackoverflow
Solution 10 - IosFormigaNinjaView Answer on Stackoverflow
Solution 11 - IosRavi KumarView Answer on Stackoverflow
Solution 12 - Iosdaniel.gindiView Answer on Stackoverflow
Solution 13 - IosSiempayView Answer on Stackoverflow
Solution 14 - IosMuhammad NumanView Answer on Stackoverflow
Solution 15 - IosTamás SengelView Answer on Stackoverflow