20

My iOS app is in Arabic (right-to-left) language only. Prior to iOS 9 the views layout and view animations were all by default left-to-right. So, I had customised the complete app and had reversed the default behaviour e.g. back button in navigation bar was set to be on the right instead of default left.

But now when the app is compiled using latest SDK (Xcode 7 beta 4), everything is the opposite of what I need.

Is there any simple way to force the app to show views and behave like iOS 8 and 7?

I searched and found a solution but it involves changing the constraints(Uncheck the "Respect language direction") for all views. But this is not a feasible solution in large projects.

This is a screenshot after compiling with Xcode 7 beta 4. .

and this is a screenshot when compiled with Xcode 6. enter image description here

Abdullah Umer
  • 4,234
  • 5
  • 36
  • 65

7 Answers7

22

Edit: The following code may cause unexpected behavior as @wakachamo pointed out. So, please watch out for issues e.g. Interactive pop gesture doesn't work, alertviews don't show, etc. Its better to follow the instruction provided by @wakachamo if this doesn't work for you

Add this to app delegate didFinishLaunchingWithOptions method.

[[UIView appearance] setSemanticContentAttribute:UISemanticContentAttributeForceLeftToRight];

Also add guard to support earlier version so that the property doesn't cause any crash.

if([[[UIView alloc] init] respondsToSelector:@selector(setSemanticContentAttribute:)]) {
        [[UIView appearance] setSemanticContentAttribute:UISemanticContentAttributeForceLeftToRight];
    }

[[UIView alloc] init] instead of [UIView appearance] because respondsToSelector is not currently working with [UIView appearance] for setSemanticContentAttribute. You can also add iOS 9 Check

#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v)  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)

if(SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"9.0")) {
        [[UIView appearance] setSemanticContentAttribute:UISemanticContentAttributeForceLeftToRight];
    }
Kamran Khan
  • 1,367
  • 1
  • 15
  • 19
  • This is not a supported configuration and will lead to several bugs and inconsistencies in your app. – wakachamo Aug 24 '15 at 19:04
  • Yes it may be the case, but it is the only thing that works till now for navigationcontrollers, to make them left to right, as far as I know. For individual items semanticContentAttribute works best as you described. – Kamran Khan Aug 25 '15 at 06:26
  • Thanks guys! I had found a more simple solution for my case. Please see my answer. – Abdullah Umer Aug 27 '15 at 14:44
  • 1
    I had to add this string: ' [[UIView appearanceWhenContainedIn:NSClassFromString(@"_UIAlertControllerView"), nil] setSemanticContentAttribute:UISemanticContentAttributeUnspecified]; ' Otherwise actionSheets won't display any buttons except for cancel button. – mas'an Sep 30 '15 at 12:33
  • 2
    Regarding navigation controllers, setting the semanticContentAttribute on UINavigationController.view should do the right thing. – wakachamo Feb 28 '16 at 10:18
  • @AbdullahUmer where's ur answer.. add url – iosMentalist Nov 23 '17 at 15:22
16

i found the correct way from Apple Developer Forums

here iOS 9 beta - UIAlertController is not working

just add this code to make alertview work with it

 if(SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"9.0")) {
            [[UIView appearance] setSemanticContentAttribute:UISemanticContentAttributeForceLeftToRight];

    [[UIView appearanceWhenContainedIn:[UIAlertController class], nil] setSemanticContentAttribute:UISemanticContentAttributeUnspecified];
    [[UIView appearanceWhenContainedIn:[UIAlertView class], nil] setSemanticContentAttribute:UISemanticContentAttributeUnspecified];



}
iDevSmart
  • 161
  • 1
  • 2
13

I know its too late to answer. But I have figured it out (Only the navigation bar issue).

The answer is adapted from @Kamran Kan. Thanks @Kamran.

Jus replace the UIView with UINavigationBar in @Kamran's answer. then the code will be as follows.

#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v)  ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)

if(SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"9.0")) {
    [[UINavigationBar appearance] setSemanticContentAttribute:UISemanticContentAttributeForceLeftToRight];
}

Since it is only effect the UINavigationBar, the other controls won't effect. So the UIAlertView is working fine...

Rishad Appat
  • 1,786
  • 1
  • 15
  • 30
  • 1
    perfect answer for nav bar – Mehul Feb 06 '17 at 19:06
  • Thanks, this answer works for my question https://stackoverflow.com/questions/45736141/position-of-navigation-buttons-in-rtl-languages-are-not-correct-in-ipad?noredirect=1#comment78460346_45736141 – Mohnish Hirudkar Aug 18 '17 at 10:38
7

There is no easy way. It's recommended that you migrate to standard API as much as possible long-term.

Another approach is to set the semanticContentAttribute of all the affected views to UISemanticContentAttributeForceLeftToRight, but this is just as feasible as setting all your constraints to use Left/Right instead of Leading/Trailing. In addition to this, you'll also have to gate these calls around an availability check if you're targeting iOS <9.

wakachamo
  • 1,723
  • 1
  • 12
  • 18
  • i am having a problem in the UITextField placeholder. it is still showing from right to left. I tried to alter the: UITextField.appearance(). semanticContentAttribute and UITextField.appearance().UITextField.appearance().makeTextWritingDirectionLeftToRight(nil) but useless – iosMentalist Nov 23 '17 at 15:48
5

SWIFT 2 Code

if #available(iOS 9.0, *) {
     myView.semanticContentAttribute = .ForceLeftToRight
}
Husam
  • 8,149
  • 3
  • 38
  • 45
4

For SWIFT 3

if #available(iOS 10.0, *) {
     UIView.appearance().semanticContentAttribute = .forceLeftToRight
}
Ramkrishna Sharma
  • 6,961
  • 3
  • 42
  • 51
3

Use Storyboard and choose for each specific view controllers

Semantic->Force Left-to-Right.

Force Left-to-Right

iosMentalist
  • 3,066
  • 1
  • 30
  • 40
Sedat Y
  • 561
  • 5
  • 6