若客戶端使用者不只單一國家,就會需要有變更app語言的功能,
之前查了一些資訊都是需要退出後才能變更語言包,
然後我有找到網路神人Roman Sorochak寫的範例,不用退出app就能變更語言包,覺得超棒的
將所有元件先與viewcontroller連結好,且將所有元件的String都設定好
續前篇的佈局,加上一個變更語言的按鈕,因為想區別一下與Storyboard上是不同語言所以會以英文、日文、韓文作為變更語言的示範
示範:
@IBOutlet weak var infoTextView: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
infoTextView.text = "Please enter your basic information"
}
創建Localizable.strings的新檔案
點擊Localizable按鈕
接著到Project Navigator中的Project下的info
可以在紅框處添加新的語言包,如下圖
各種語言都可以以此方式創建語言包
import UIKit
extension String {
//在String後添加.localized即可以轉用設定之本地化字串
var localized: String {
return Bundle.localizedBundle.localizedString(forKey: self, value: nil, table: nil)
}
//在圖片檔名後添加.localizedImage即可以使用該語言包內相應檔名的圖片
var localizedImage: UIImage? {
return localizedImage()
?? localizedImage(type: ".png")
?? localizedImage(type: ".jpg")
?? localizedImage(type: ".jpeg")
?? UIImage(named: self)
}
private func localizedImage(type: String = "") -> UIImage? {
guard let imagePath = Bundle.localizedBundle.path(forResource: self, ofType: type) else {
return nil
}
return UIImage(contentsOfFile: imagePath)
}
}
extension Bundle {
static var localizedBundle: Bundle {
let languageCode = Language.language.rawValue
guard let path = Bundle.main.path(forResource: languageCode, ofType: "lproj") else {
return Bundle.main
}
return Bundle(path: path)!
}
}
private let appleLanguagesKey = "AppleLanguages"
enum Language: String {
case english = "en"
case Japanese = "ja"
case Korean = "ko"
static var language: Language {
get {
if let languageCode = UserDefaults.standard.string(forKey: appleLanguagesKey),
let language = Language(rawValue: languageCode) {
return language
} else {
//獲取偏好語言第一順位的字段
let preferredLanguage = NSLocale.preferredLanguages[0] as String
let index = preferredLanguage.index(
preferredLanguage.startIndex,
offsetBy: 2
)
//本地化語言包中若有與偏好語言第一順位相符的語言包,則顯示該語言包,若無相符,一律顯示英文
guard let localization = Language(
rawValue: preferredLanguage.substring(to: index)
) else {
return Language.english
}
return localization
}
}
set {
guard language != newValue else {
return
}
//變更app內中的語言
UserDefaults.standard.set([newValue.rawValue], forKey: appleLanguagesKey)
//要執行synchronize()才會真的寫入資料中
UserDefaults.standard.synchronize()
UIApplication.shared.windows[0].rootViewController = UIStoryboard(
name: "Main",
bundle: nil
).instantiateInitialViewController()
}
}
}
將前置作業中設定好的字串後面加上.localized
示範:infoTextView.text = "Please enter your basic information".localized
然後將變更語言的按鈕”Touch up inside”連結至viewcontroller中,使用彈窗功能將各語言選項放進彈窗中,
點擊該語言按鈕後,即可以更換語言包
示範:
@IBAction func changeLanguage(_ sender: Any) {
let alert = UIAlertController(
title: "alert_change_language_title".localized,
message: nil,
preferredStyle: .actionSheet
)
func addActionLanguage(language: Language) {
alert.addAction(
UIAlertAction(
title: language.rawValue.localized,
style: UIAlertAction.Style.default,
handler: { _ in
Language.language = language
})
)
}
addActionLanguage(language: Language.english)
addActionLanguage(language: Language.Japanese)
addActionLanguage(language: Language.Korean)
alert.addAction(
UIAlertAction(
title: "alert_cancel".localized,
style: UIAlertAction.Style.cancel,
handler: nil
)
)
present(alert, animated: true, completion: nil)
}
將要本地化的字串列好(XXXXX.localized中的XXXXX),然後更新切換成該語言包時要顯示的字串
示範:
英文"Please enter your basic information" = "Please enter your basic information";
日文"Please enter your basic information" = "基本情報を入力してください";
韓文"Please enter your basic information" = "기본정보를 입력해주세요";
以上變更語言的功能完成!