Changing to right to left RTL programmatically

2019-03-15 23:37发布

问题:

I'm working on an App which supports two languages: English and Arabic. When the user changes the language to Arabic, I need my app to make the text right-to-left (RTL).

I searched for this issue, and I found this answer about supporting RTL.

I would like to do apply the the above answer but in a programmatically way, because I need to change from LTR to RTL while the App is running.

回答1:

in Swift 4 try this,

//FOR RIGHT TO LEFT
 UIView.appearance().semanticContentAttribute = .forceRightToLeft

//FOR LEFT TO RIGHT
 UIView.appearance().semanticContentAttribute = .forceLeftToRight


回答2:

I changed my app to right to left RTL by using this :

self.transform = CGAffineTransformMakeScale(-1.0, 1.0)

This flipped the view, then i flipped the objects in the view like this:

label.transform = CGAffineTransformMakeScale(-1.0, 1.0)
textField.transform = CGAffineTransformMakeScale(-1.0, 1.0)
image.transform = CGAffineTransformMakeScale(-1.0, 1.0)

This made my views RTL instead of changing all constraints or rebuild the app as RTL.



回答3:

03/05/2018 : Since @SalmaGh have answers his owned Question.
But the solution would make your UI/UX mess up badly.
I would give a suggestion on how i would solve this issue.

This answer was refer from multiple answer who would deserve to be upvoted instead of downvote.

Reason: Adding a language switcher to your app is only going to make it more confusing

This solution is required since some of arabic language such as mention by @Afshin M. Khiabani are done in App Manually instead of Library/Framework/Device Default. this gives developer more control over their apps. however this method are not prefer.

WARNING: This will mess up Horizantal Scrollview with Subviews

But if you must force LTL view to be RTL. suggest to used IOSPercy and Jaydip answer. but please do make a flagging for checking. such as let isArabic = false or used user default.


First enter code inside AppDelegate didFinishLaunchingWithOptions
why should we put this checking in the AppDelegate is because UIView on AppDelegate would be the superview to all view controller.

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
     self.ChangeLayout()
    return true
}

func ChangeLayout(){
    var languageCode = ""
    if let value = UserDefaults.standard.string(forKey: "Applanguage") {
        languageCode = value
    }else{
        languageCode = ""
    }
    if(languageCode == "ar"){
        UIView.appearance().semanticContentAttribute = .forceRightToLeft
    }else{
        UIView.appearance().semanticContentAttribute = .forceLeftToRight
    }
}

This code will automatically Load the apps in RTL mode if Applanguage save "ar" however this will only happen once when you reopen the apps.


But you can access the function by calling the AppDelegate Function Like so:

        let appDelegate: AppDelegate? = UIApplication.shared.delegate as? AppDelegate
        appDelegate?.ChangeLayout()


Then Call TopMost ViewController such as LoadingScreen or something to make the Reload flow.



回答4:

Since it is your own application, I'm going to assume that you have control over it's UI elements.

If so, not only can you provide NSLayoutConstraint which satisfy your requirements, you can also specify alignment for text and buttons representation: NSTextAlignment.

Since you cannot control System Settings programmatically, keep in mind that your app will no longer take advantage of natural constraints, such as leading or trailing.



回答5:

Use this line of code it will change layout without closing application. From right to left

UIView.appearance().semanticContentAttribute = .forceRightToLeft

And for Left to Right Flip

UIView.appearance().semanticContentAttribute = .forceLeftToRight

and if you want to change textfield layout or text change then use this code because i faced this issue . textfield's texts was not changning layout. check this code to change layout of textfield text

extension UITextField {
open override func awakeFromNib() {
        super.awakeFromNib()
        if UserDefaults.languageCode == "ar" {
            if textAlignment == .natural {
                self.textAlignment = .right
            }
        }
    }
}


回答6:

Do you mind if I ask why you need this?

I would highly recommend thinking twice before doing this, mostly because it provides a confusing user experience. Users expect their apps to follow the system language, and therefore not have any method of choosing the language inside the app.

iOS makes it very easy for you to do it the right way; if you use Auto Layout, build your custom controls upon UIKit API and use NSLocalizedString, everything will do the right thing at runtime for your users.



回答7:

Use Following lines in method didFinishLaunchingWithOptions when You want Arabic language layout, For SWIFT

UIView.appearance().semanticContentAttribute = .forceRightToLeft

For Objective C

[UIView appearance].semanticContentAttribute = UISemanticContentAttributeForceRightToLeft;

and reload the app using

[self application:app didFinishLaunchingWithOptions:nil];

in some other method in appDelegate. Call that method where you are changing app language.

Use vice versa for english localisation of app.



回答8:

Extension Solution To Flip UIView & UILabel

UIViews Extension
It can work with Anything as long it is a View.

extension UIView{
   func flipView(){
       self.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
   }
}

Used it like so *

This Will Flip Views and Item inside that view.

UIView.flipView()



UI Label Extension
I made a separate Extension for UILabel Because it is related to Text Alignment

extension UILabel{
    func flipLabel(align: NSTextAlignment){
        self.textAlignment = align
        self.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
    }
}

Used it on UILabel like so

 UILabel.flipLabel(align: .right)

Hope this help others flip views easier.