Install iOS language without rebooting

I know quite a few posts that say this should not be done, or it is impossible. I was busy with a few ideas, and now I am asking this question because I want to be absolutely sure that there are no other options.

Option 1:

The most popular solution is to change AppleLanguages , as in this post. I do not mind the need to restart, so this would be an acceptable solution for me, except that you cannot restart the application programmatically (you cannot find the method or reject Apple). Asking the user to manually restart the application would not be ideal.

Option 2:

The next solution is to get the appropriate package and do a localizedStringForKey search for each UILabel , UIButton , etc. This may be a bit tedious, but for me it is normal since I already added localizationProperties (similar to this ) to these views in order to have a centralized line file.

AppDelegate.swift:

 static var userLanguage: String? { set { let defaults = NSUserDefaults.standardUserDefaults(); defaults.setObject(newValue, forKey: LanguageKey); defaults.synchronize(); let storyboard = UIStoryboard(name: "Main", bundle: NSBundle.mainBundle()); instance.window?.rootViewController = storyboard.instantiateInitialViewController(); } get { let defaults = NSUserDefaults.standardUserDefaults(); return defaults.stringForKey(LanguageKey); } } 

Localization.swift:

 private var bundle: NSBundle { get { let bundle: NSBundle; #if TARGET_INTERFACE_BUILDER bundle = NSBundle(forClass: self.dynamicType); #else bundle = NSBundle.mainBundle(); #endif let lang: String; if(AppDelegate.userLanguage == nil || AppDelegate.userLanguage == "en") { lang = "Base"; } else { lang = AppDelegate.userLanguage!; } let path = bundle.pathForResource(lang, ofType: "lproj"); if(path != nil) { let toreturn = NSBundle(path: path!); if(toreturn != nil) { return toreturn!; } } return bundle; } } extension UILabel { @IBInspectable var localizedText: String? { get { return "" } set { if(newValue != nil) { text = bundle.localizedStringForKey(newValue!, value:"", table: nil); } } } } 

The problem with option 2 is that it only sets the language for these fields. The direction of the layout will not change, and files such as language layouts will not be used.

By expanding on UIApplication , I can specify a user userInterfaceLayoutDirection that successfully changes all layouts between LTR and RTL.

DemoApplication.swift:

 class DemoApplication: UIApplication { override internal var userInterfaceLayoutDirection: UIUserInterfaceLayoutDirection { get { if(AppDelegate.userLanguage == "ar") { return UIUserInterfaceLayoutDirection.RightToLeft; } return UIUserInterfaceLayoutDirection.LeftToRight; } } } 

Now when I install AppDelegate.userLanguage , the application will reset to the initial view controller, displaying the new language, flipping the layout between LTR and RTL. This does not concern the problem with specific language files, and I also noticed that the text remains left or right within its own borders.

Since I can’t find the source code for the native iOS classes, I don’t see which language specific variables are set at startup, so I assumed that it was associated with NSBundle.mainBundle . I tried to override it using the swizzling method.

 extension NSBundle { override public class func initialize() { struct Static { static var token: dispatch_once_t = 0; } // make sure this isn't a subclass if (self !== NSBundle.self) { return; } dispatch_once(&Static.token) { do { try jr_swizzleClassMethod("mainBundle", withClassMethod: "mainBundleExt"); } catch { print("\(error)"); } } super.initialize(); } public class func mainBundleExt() -> NSBundle { let bundle = self.mainBundleExt(); // Due to swizzling, this is the "super" method let lang: String; if(AppDelegate.userLanguage == nil || AppDelegate.userLanguage == "en") { lang = "Base"; } else { lang = AppDelegate.userLanguage!; } let path = bundle.pathForResource(lang, ofType: "lproj"); if(path != nil) { let toreturn = NSBundle(path: path!); if(toreturn != nil) { return toreturn!; } } } } 

This does not work, it seems that the default is mainBundle .

So my question is: how is the mainBundle assigned a value? What other language variables are set at startup, for example userInterfaceLayoutDirection . I assume that there are 2 or 3 of these variables. Finally, is this possible for work or am I just wasting my time?

Thanks.

+10
ios swift localization
source share
2 answers

I had this problem before and I used the library. it helped me change my language on the fly. try using this: https://github.com/Decybel07/L10n-swift

 L10n.shared.language = "en" L10n.shared.language = "en-GB" 

At run time, you can switch the language at any time by setting the language property

0
source share

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

 UIView.appearance().semanticContentAttribute = .forceRightToLeft 

And for flip from left to right

 UIView.appearance().semanticContentAttribute = .forceLeftToRight 

and if you want to change the layout of the text box or text change, use this code because I ran into this problem. Text text fields did not change the layout. check this code to change the location of the text in the text box

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

All Articles