How Can I set Localised Direction within application?(RTL if user select arabic, LTR is selected language is English)

My Application must support Arabic(right to left direction) and English(left to right direction) language, I need to set UI and based on user select language from my application.

I will implement UI with NSLayoutConstraint so it can update UI automatically, based on leading and trailing constraints.

  • Why does the LLDB Debugger constantly fail to attach?
  • Get device token for push notifications after app was deleted
  • CAShapeLayer Animating Path Glitches / Flickers (From Ellipse to Rect and back)
  • Xcode 4.2 with ARC: will my code run even on iOS devices with firmware older than 5.0?
  • How to enable native resolution for apps on iPhone 6 and 6 Plus?
  • iOS 8 popoverpresentationcontroller popoverlayoutmargin not working
  • Now My Question is how can i achieve this? As My device language is say English and from my application user select Arabic(limited to my app only), So my Flow,UI,Animations etc should be right to left.

    here are the sample snap for ui Direction
    enter image description here
    enter image description here

    Thanks

    2 Solutions Collect From Internet About “How Can I set Localised Direction within application?(RTL if user select arabic, LTR is selected language is English)”

    Update (iOS 9+)

    Some says that this way is not official and may cause problems.

    UI direction can be forced now without closing the app:

    UIView.appearance().semanticContentAttribute = .forceRightToLeft
    

    Note, bars in iOS 9 can’t be forced to RTL (Navigation and TabBar). While it get forced with iOS 10.

    The only remaining thing that can’t be forced RTL in iOS 10 is the default back button.

    I am not sure if we still have to handle localized strings if
    controller closed and re-opened.

    Below iOS 9

    Short answer:

    Even if you managed to do that. Layout will not change according to
    the language selected without an app. restart by user.

    Apple’s guide line:

    Apple doesn’t provide that because they don’t prefere to allow the user
    to change language from inside the app. Apple pushes the developers to
    use the device language. and not to change it from inside the app at all.

    Workarwound:

    Some apps that supports Arabic language notes that’s in the
    settings page where the user can change the language. noting to the
    user that layout will not take effect without an app. restart. store
    link for sample app

    Example code to change app language to arabic:

    [[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithObjects:@"ar", @"en", nil] forKey:@"AppleLanguages"];
    

    That won’t take effect without a restart

    Alternative Solution:

    Is to provide your own localization solution:

    1. Do not Use Base Internationalization.
    2. Create one strings file for each language.
    3. Place the change language feature in a ViewController that starts before any other ViewController even before your main one.
    4. Set the constraints and strings for your views in viewDidLoad method for all view controllers.

    You don’t have to satisfy point 5 if you didn’t Use Base Internationalization

    1. Change every constraint at the storyboard from Leadring/Trailing to Right/Left.

    Language class sample:

    @implementation LanguageDetails
    
    @synthesize language;
    @synthesize bundle;
    
    #define LANGUAGE_KEY @"LANGUAGE_KEY"
    
    // language var is also the strings file name ar or en
    
    - (id)init
    {
        if (self = [super init]) {
    
            language = [[[NSBundle mainBundle] preferredLocalizations] objectAtIndex:0];
    
            if (![language isEqualToString:@"ar"])
                language = @"en";
    
            language = [Common valueForKey:LANGUAGE_KEY defaultValue:language];
    
            bundle = [NSBundle mainBundle];
        }
        return  self;
    }
    
    - (BOOL)rtl {
        return [NSLocale characterDirectionForLanguage:language] == NSLocaleLanguageDirectionRightToLeft;
    }
    
    - (void)changeLanguage
    {
        if ([language isEqualToString:@"ar"])
            language = @"en";
        else
            language = @"ar";
    
        [Common setValue:language forKey:LANGUAGE_KEY];
    }
    
    - (void)changeLanguageTo:(NSString *)lang
    {
        language = lang;
    
        [Common setValue:language forKey:LANGUAGE_KEY];
    }
    
    - (NSString *) LocalString:(NSString *)key {
        return NSLocalizedStringFromTableInBundle(key, language, bundle, nil);
    }
    
    @end
    

    Initialise an object of this class in your singlton class.

    @ashwin, I was trying to do the exact same thing as you were.

    I was hoping to find I could turn my app into a RTL language (right to left) just by changing something in the info.plist, appdelegate or who knows what. The idea is that someone with a LTR device can have my app in RTL, changing it within the app and with no need to restart it.

    Looks like there is not such a thing (I’ll be glad to hear if anyone disagrees with this). However, I’ve found some options that are not that bad.

    1. It turns out you can force a specific view to be LTR or RTL. Thus you can set this property on every view of your app. The way you do it is up to you.

      self.view.semanticContentAttribute = UISemanticContentAttributeForceRightToLeft;

    Reference: UISemanticContentAttribute

    1. You can always flip views horizontally until you get the desired setup.

    [view setTransform:CGAffineTransformMakeScale(1, 1)];

    Here’s some code that might help you.

    void reloadRTLViewAndSubviews(UIView *view)
    {
        reloadRTLViews(@[view]);
        reloadRTLViews([view subviews]);
    }
    
    void reloadRTLViews(NSArray *views)
    {
        if (isRTL())
        {
            [views enumerateObjectsUsingBlock:^(UIView* view,
                                                NSUInteger idx,
                                                BOOL * stop)
             {
                 [view setTransform:CGAffineTransformMakeScale(-1, 1)];
             }];
        }
        else
        {
            [views enumerateObjectsUsingBlock:^(UIView* view,
                                                NSUInteger idx,
                                                BOOL * stop)
             {
                 [view setTransform:CGAffineTransformMakeScale(1, 1)];
             }];
        }
    }
    
    BOOL isRTL()
    {
        return isRTL_app();
    }
    
    BOOL isRTL_device()
    {
        BOOL isRTL = ([NSLocale characterDirectionForLanguage:[[NSLocale preferredLanguages] objectAtIndex:0]] == NSLocaleLanguageDirectionRightToLeft);
    
        return isRTL;
    }
    
    BOOL isRTL_scheme()
    {
        BOOL isRTL = ([UIView userInterfaceLayoutDirectionForSemanticContentAttribute:[UIView new].semanticContentAttribute] == UIUserInterfaceLayoutDirectionRightToLeft);
    
        return isRTL;
    }
    
    BOOL isRTL_app()
    {
        NSString *languageIdentifier = [AppDataManager sharedManager].languageIdentifier;
        NSArray *rtl_languages = @[@"ar"];
    
        BOOL isRTL;
    
        if ((languageIdentifier == nil) || (languageIdentifier.length == 0))
        {
            isRTL = (isRTL_device() || isRTL_scheme());
        }
        else if ([rtl_languages containsObject:languageIdentifier])
        {
            isRTL = YES;
        }
        else
        {
            isRTL = NO;
        }
    
        return isRTL;
    }
    
    BOOL deviceLanguageDirectionEqualAppLanguageDirection()
    {
        if ((isRTL_device() || isRTL_scheme()) && isRTL())//All RTL
        {
            return YES;
        }
        else if (!(isRTL_device() || isRTL_scheme()) && !isRTL())//All LTR
        {
            return YES;
        }
    
        return NO;//RTL-LTR or LTR-RTL
    }
    
    void transformViews(NSArray *views)
    {
        [views enumerateObjectsUsingBlock:^(UIView* view,
                                            NSUInteger idx,
                                            BOOL * stop)
         {
             [view setTransform:CGAffineTransformMakeScale(-1, 1)];
         }];
    }
    

    So if you were to change a UIViewController to be in RTL you can make all the setup so that it would suffice to:

    reloadRTLViewAndSubviews(self.view);
    

    Note: this is not the way it should be and Apple’s guidelines say that the language should be change from the iOS settings. But this solution works if the language must be changed within the app and a language direction change between LTR and RTL is involved. And no app reset needed either.

    I hope it helped.