App 内部语言切换

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类型在切换语言时不能实时更新。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1、通过CocoaPods安装项目名称项目信息 AFNetworking网络请求组件 FMDB本地数据库组件 SD...
    阳明AI阅读 16,025评论 3 119
  • D632: 中午回家,推开门,一只可爱的“小松鼠”映入眼帘。背对着妈妈坐在自己的餐椅上,埋头一点一点、从小手里面卖...
    鱼羊正史阅读 191评论 0 3
  • 第四十九章 前情提要:北极光光神焱爱腾空出世,管家陈森与淼寒父母失去联系,暗中出手帮助攸夜的少年凛亦被黑暗污染。王...
    腐草为滢阅读 288评论 0 3
  • 昨天晚上看了一档节目,是说一个男子和两个女人的故事。大体是这个男子与前任同甘共苦,时间都忙于做生意没有去领证,却也...
    路_1ce2阅读 663评论 0 1
  • 1,缺啥补啥,怕啥练啥; 2,一切为我所用,所用为团队家; 3,我想变,我要变,我不得不变,我会变得越来越好。 今...
    刘大畅阅读 193评论 0 0