美文网首页
App 内部语言切换

App 内部语言切换

作者: 有虫吃 | 来源:发表于2018-09-11 11:47 被阅读0次

    1、App 的语言配置列表可从如下方式读取:

    let languageArray = UserDefaults.standard.object(forKey: "AppleLanguages") as! [String]
    

    默认语言为数组的第一个值所存储的语言,可以通过更改该数组值得存储顺序来实现app内如的语言切换。

    UserDefaults.standard.set(["zh-Hans-CN", "en-CN"], forKey: "AppleLanguages")
    

    2、更改完语言数组以后需要重新设置app的rootViewController

    //Bundle.main.onLanguage()
    let storyboard = UIStoryboard.init(name: "Main", bundle: nil)
    let tabBarController = storyboard.instantiateViewController(withIdentifier: "tabBarController") as! UITabBarController
            
     UIApplication.shared.keyWindow?.rootViewController = tabBarController
     UIApplication.shared.keyWindow?.backgroundColor = UIColor.white
     UIApplication.shared.keyWindow?.makeKeyAndVisible()
    

    3、此时发现并能实时的切换语言,因为在app启动时资源文件已经读取,此时并未更改读取的资源文件。因此需要在切换语言是更换资源路径。继承Bundle,重写localizedString本地化函数,写一个扩展将Bundle类型替换为自定义的BundleEx类型,在语言切换时调用Bundle.main.onLanguage()然后再更换为rootViewController。

    class BundleEx: Bundle {
        
        override func localizedString(forKey key: String, value: String?, table tableName: String?) -> String {
            if let bundle = Bundle.getLanguageBundel() {
                return bundle.localizedString(forKey: key, value: value, table: tableName)
            }else {
                return super.localizedString(forKey: key, value: value, table: tableName)
            }
        }
    }
    extension Bundle {
        private static var onLanguageDispatchOnce: ()->Void = {
            //替换Bundle.main为自定义的BundleEx
            object_setClass(Bundle.main, BundleEx.self)
        }
        
        func onLanguage(){
            Bundle.onLanguageDispatchOnce()
        }
        
        class func getLanguageBundel() -> Bundle? {
            var languageString = "Base"
            let languageArray = UserDefaults.standard.object(forKey: "AppleLanguages") as! [String]
            if languageArray.first == "zh-Hans-CN"{
                languageString = "zh-Hans"
            }
            let languageBundlePath = Bundle.main.path(forResource: languageString, ofType: "lproj")
            guard languageBundlePath != nil else {
                return nil
            }
            let languageBundle = Bundle.init(path: languageBundlePath!)
            guard languageBundle != nil else {
                return nil
            }
            return languageBundle!
            
        }
    }
    

    注意事项:storyboard类型和xib类型的本地化文件需要是.strings类型,如果是storyboard类型和xib类型在切换语言时不能实时更新。

    相关文章

      网友评论

          本文标题:App 内部语言切换

          本文链接:https://www.haomeiwen.com/subject/amaygftx.html