添加语言库
- 点击项目 -> PROJECT -> Info -> Localizations -> + , 添加需要的语言;
- 添加完成的语言库如下所示:
- 创建Localizable.strings
- 然后选择新创建的 Localizable.string, 选中所需要的语言;
Localizable.strings 文件写入
- 添加语言库成功之后, Localizable.strings就生成了English、Chinese Simplified、Chinese Traditional三个语言文件;
- Localizable.strings 文件中写入, 以"key" = “value”; 这样的格式;
- English:
INTERNATIONALIZATION = "Internationalization";
CHANGE = "switch";
HANDSOME = "Handsome Boy";
- Chinese Simplified
INTERNATIONALIZATION = "国际化";
CHANGE = "切换";
HANDSOME = "帅哥";
- Chinese Traditional
INTERNATIONALIZATION = "國際化";
CHANGE = "切換";
HANDSOME = "帥哥";
YDWLocalizationHelper
该工具类可以直接拖入工程中使用, 主要实现功能:
- 第一次进入App时, 自动根据系统的语言设定当前App的语言;
- 保存当前用户设定的语言;
- 自定义切换语言功能;
- 控件赋值的获取和设定;
- 切换语言后替换掉mainBundle为当前语言的bundle;
import UIKit
class YDWLocalizationHelper: NSObject {
fileprivate static let kSharedSettingsKey = "DefaultUserSettings"
var language: Language
enum Language: String {
case Chinese = "zh-Hans"
case English = "en"
case Tradition = "zh-Hant"
case Vietnamese = "vi"
var code: String {
return rawValue
}
}
// MARK: 创建单例
static let shared: YDWLocalizationHelper = {
let appSettings: YDWLocalizationHelper
if let savedData = UserDefaults.standard.object(forKey: YDWLocalizationHelper.kSharedSettingsKey) as? Data,
let defaultSettings = NSKeyedUnarchiver.unarchiveObject(with: savedData) as? YDWLocalizationHelper {
appSettings = defaultSettings
} else {
appSettings = YDWLocalizationHelper()
}
return appSettings
}()
// MARK: 获取键值
func valueWithKey(key: String!) -> String {
let str = NSLocalizedString(key, comment: "")
return str
}
// MARK: - 保存用户当前语言
static func saveSharedInstance() {
let data = NSKeyedArchiver.archivedData(withRootObject: YDWLocalizationHelper.shared)
UserDefaults.standard.set(data, forKey: YDWLocalizationHelper.kSharedSettingsKey)
}
static func localeIsChinese() -> Language {
if let lang = Locale.preferredLanguages.first {
if lang.hasPrefix("zh") {
if lang.contains("Hant") || lang.contains("Trad") {
return .Tradition
}
return .Chinese
} else if lang.contains("en") {
return .English
} else if lang.hasPrefix("viet") {
return .Vietnamese
} else {
return .English
}
} else {
return .English
}
}
// MARK: 首次进入语言
override init() {
language = YDWLocalizationHelper.localeIsChinese()
super.init()
}
}
private var bundleByLanguageCode: [String: Foundation.Bundle] = [:]
extension YDWLocalizationHelper.Language {
var bundle: Foundation.Bundle? {
if let bundle = bundleByLanguageCode[code] {
return bundle
} else {
let mainBundle = Foundation.Bundle.main
if let path = mainBundle.path(forResource: code, ofType: "lproj"),
let bundle = Foundation.Bundle(path: path) {
bundleByLanguageCode[code] = bundle
return bundle
} else {
return nil
}
}
}
}
// 当调用YDWLocalizationHelper.Language切换语言后替换掉mainBundle为当前语言的bundle
class Bundle: Foundation.Bundle {
override func localizedString(forKey key: String, value: String?, table tableName: String?) -> String {
if let bundle = YDWLocalizationHelper.shared.language.bundle {
return bundle.localizedString(forKey: key, value: value, table: tableName)
} else {
return super.localizedString(forKey: key, value: value, table: tableName)
}
}
}
语言切换
- AppDelegate中: object_setClass(Foundation.Bundle.main, Bundle.self)
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
object_setClass(Foundation.Bundle.main, Bundle.self)
return true
}
- 使用:设定时只需要在控件上, 通过YDWLocalizationHelper.shared.valueWithKey(key: “INTERNATIONALIZATION”)来设定即可; 而切换语言只需要通过设定YDWLocalizationHelper.shared.language = .Chinese即可;(其中valueWithKey和YDWLocalizationHelper.shared.language实现如下)
// comment 是传参, 假如value中需要外界来决定内容,可以用%@,然后comment传参
func valueWithKey(key: String!) -> String {
let str = NSLocalizedString(key, comment: "")
return str
}
// 切换语言时,只要设置就可以:
YDWLocalizationHelper.shared.language = .Chinese // .Chinese
- 最后重载RootViewController即可:
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.setupRootViewController()
- 对于story 中的国际化, 需要重设一下RootViewController
func resetRootViewController() {
if let appdelegate = UIApplication.shared.delegate {
let storyBoard = UIStoryboard.init(name: "Main", bundle: nil)
if let mainController = storyBoard.instantiateViewController(withIdentifier: "rootViewController") as? UINavigationController {
appdelegate.window??.rootViewController = mainController
}
}
}
刷新界面
对于所有界面的刷新最方便的就是重新设置 rootViewController, 将keyWindow先变黑,假装loading个几秒,再变回来即可。如果需要再次回到之前所在页面,再添加相应的跳转VC的方法;
func chooseLanguage(menu: [String : Any]) {
let language = menu["language"] as! String
var noticeContent = "正在设置语言..."
if language == "中文(简体)" {
noticeContent = "正在设置语言..."
YDWLocalizationHelper.shared.language = .Chinese
} else if language == "中文(繁體)" {
noticeContent = "正在設置語言..."
YDWLocalizationHelper.shared.language = .Tradition
} else if language == "English" {
noticeContent = "Setting Language..."
YDWLocalizationHelper.shared.language = .English
} else if language == "Tiếng Việt" {
noticeContent = "Thiết lập ngôn ngữ..."
YDWLocalizationHelper.shared.language = .Vietnamese
} else {
noticeContent = "正在设置语言..."
YDWLocalizationHelper.shared.language = .Chinese
}
if UIApplication.shared.delegate != nil {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
appDelegate.setupRootViewController()
}
let backView = UIView(frame: UIScreen.main.bounds)
backView.backgroundColor = .black
UIApplication.shared.keyWindow?.addSubview(backView)
YDWToast.showToast(text: noticeContent, duration: 2, location: .center)
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 2) {
UIView.animate(withDuration: 0.2, animations: {
backView.alpha = 0
}) { (isFinished) in
backView.removeFromSuperview()
}
}
}