最近做了一下应用内多语言的切换功能,百度了一下,看到很多方法,但是我这个人比较懒,代码太长就懒的看,不能复制就能使用也懒的看.... 只到看到了一种运用 runtime替换 main bundl的方法来进行切换,以此来记载一下
首先,多语言的 String 文件创建就不多说了.xib 直接创建多语言,不需要使用"key".getLabel()就可以切换
首先extension一下 String:
extension String{
func getLabel() ->String{
return NSLocalizedString(self, comment:"");
}
}
这样就可以直接在需要多语言的字符串上实现基本的语言切换"key".getLabel()
然后extension Bundle 把现在运用的 bundle 替换成需要使用的 bundle
import Foundation
enum Language :String{
case english ="en"
case chinese ="zh-Hans"
}
/**
* 当调用onLanguage后替换掉mainBundle为当前语言的bundle
*/
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? {
let languageBundlePath =Bundle.main.path(forResource:UserDefaults.standard.value(forKey:"appLanguage")as?String, ofType:"lproj")
// print("path = \(languageBundlePath)")
guard languageBundlePath !=nil else{
returnnil
}
let languageBundle =Bundle.init(path: languageBundlePath!)
guard languageBundle !=nil else{
returnnil
}
returnlanguageBundle!
}
}
最后在切换多语言的地方调用一下
UserDefaults.standard.set([Language.english.rawValue], forKey: "AppleLanguages")
UserDefaults.standard.set(Language.english.rawValue, forKey:"appLanguage")
Bundle.main.onLanguage()
这里切换为你的根控制器就可以了:
let homeViewController =UIStoryboard(name:"Main", bundle:nil).instantiateViewController(withIdentifier:"Home")as!HomeViewController
UIApplication.shared.keyWindow?.rootViewController = homeViewController
相比于又是通知又是各种类型填写,只需要复制一下就能使用,暂时没有发现副作用.最后 想到在 extension能不能在string 初始化的时候就直接进行多语言设置呢 这样代码里面就直接使用key 就可以了 而不用调用一个方法去进行设置了.
图片多语言使用 UIImage(named: named, in:Bundle.getLanguageBundel(), compatibleWith:nil)