Swift : How to change language inside app?

前端 未结 6 1464
忘了有多久
忘了有多久 2020-12-31 19:31

i am using Localize-Swift library (Link) to localize my application and it works fine with .strings files. the problem is that i have to localize to a language

6条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2020-12-31 20:06

    In order to change the language without restarting your device you need to switch ‘lproj’ bundle.

    You can make it using this code:

    class L012Localizer: NSObject {
        class func DoTheSwizzling() {
            MethodSwizzleGivenClassName(cls: Bundle.self, originalSelector: #selector(Bundle.localizedString(forKey:value:table:)), overrideSelector:
                #selector(Bundle.specialLocalizedString(key:value:table:)))
        }
    }
    
    extension Bundle {
        @objc func specialLocalizedString(key: String, value: String?, table tableName: String?) -> String {
            let currentLanguage = Localization.currentAppleLanguage()
            var bundle = Bundle();
            if let _path = Bundle.main.path(forResource: currentLanguage, ofType: "lproj") {
                bundle = Bundle(path: _path)!
            } else {
                let _path = Bundle.main.path(forResource: "Base", ofType: "lproj")!
                bundle = Bundle(path: _path)!
            }
            return (bundle.specialLocalizedString(key: key, value: value, table: tableName))
        }
    }
    
    func MethodSwizzleGivenClassName(cls: AnyClass, originalSelector: Selector, overrideSelector: Selector){
    
        let origMethod: Method = class_getInstanceMethod(cls, originalSelector)!;
        let overrideMethod: Method = class_getInstanceMethod(cls, overrideSelector)!;
        if (class_addMethod(cls, originalSelector, method_getImplementation(overrideMethod), method_getTypeEncoding(overrideMethod))) {
            class_replaceMethod(cls, overrideSelector, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));
        } else {
            method_exchangeImplementations(origMethod, overrideMethod);
        }
    }
    

    Here we are exchanging the implementation of Bundle's localizedString method. Note: we exchanging the Implementation not the reference on the function.

    Now add this line in the Appdelegate in the didFinishLaunchingWithOptions delegate method.

    L102Localizer.DoTheSwizzling()
    

    After that you need to reload your ViewControllers. In your Main.storyboard set Root View Controller's StoryboardId to "rootnav" and paste this code to your method that switches language:

    let rootviewcontroller: UIWindow = ((UIApplication.shared.delegate?.window)!)!
    rootviewcontroller.rootViewController = self.storyboard?.instantiateViewController(withIdentifier: "rootNav")
    let mainwindow = (UIApplication.shared.delegate?.window!)!
    mainwindow.backgroundColor = UIColor(hue: 0.6477, saturation: 0.6314, brightness: 0.6077, alpha: 0.8)
    UIView.transition(with: mainwindow, duration: 0.55001, options: .transitionFlipFromLeft, animations: { () -> Void in
    }) { (finished) -> Void in
    }
    

提交回复
热议问题