swift - app國際化, 優雅切換


https://www.jianshu.com/p/e5d5fac05b8c

在開發的過程中, 可能你們的app 會有這樣的需求, 需要堅持多種語言. 怎么做到不重啟app 就更換了語言, 下面我們來討論下.
首先我們知道, 如果你的app 中需要支持多種語言, 往往我們會選擇一個Localizable.strings, 它會一種語言生成一個文件夾, 相當於一個包吧. 所以我們只要做到切換時, 選擇對應的語言包就可以了.廢話不多說, 我們開始吧.

  • 開始國際化
    點擊項目->PROJECT->Info->Localizations -> + , 添加你想要的語言, 這個談論中/英

    • 選擇想用本地化的storyboard/xib...



創建Localizable.strings

 


 

 

 

建議命名為: Localizable
  • 選擇你新創建的 Localizable.strings , Localize... 
    xx.png

    添加你語言, 最后效果



  • Localizable.strings 文件中寫入
    "key" = "value"; 這樣的格式.

  • storyboard 中生成的



  • 要想生成這種形式, 可以先切換成 , 再切換回來



  • 我們這里主要討論下怎么切換, 這些簡單配置, 就不詳細了, 請看最后的Demo.

  • 用自己創建的Bundle,想xcode 用自己指定的bundle , 達到切換語言的目的.

import Foundation class AppSettings: NSObject { fileprivate static let kSharedSettingsKey = "DefaultUserSettings" static let shared: AppSettings = { let appSettings: AppSettings if let savedData = UserDefaults.standard.object(forKey: AppSettings.kSharedSettingsKey) as? Data, let defaultSettings = NSKeyedUnarchiver.unarchiveObject(with: savedData) as? AppSettings { appSettings = defaultSettings } else { appSettings = AppSettings() } return appSettings }() static func saveSharedInstance() { let data = NSKeyedArchiver.archivedData(withRootObject: AppSettings.shared) UserDefaults.standard.set(data, forKey: AppSettings.kSharedSettingsKey) } enum Language: String { /// 請注意, 這個命名不是隨意的, 是根據你本地的語言包,可以show in finder 看到. en.lproj / zh-Hans.lproj case Chinese = "zh-Hans" case English = "en" var code: String { return rawValue } } /// 判斷手機語言是不是中文 static func localeIsChinese() -> Bool { if let lang = Locale.preferredLanguages.first { return lang.hasPrefix("zh") ? true : false ; } else { return false } } var language: Language override init() { // 第一次初始語言, 看手機是什么語言 language = AppSettings.localeIsChinese() ? .Chinese : .English super.init() } } private var bundleByLanguageCode: [String: Foundation.Bundle] = [:] extension AppSettings.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 } } } } /// 首先, 我們會在啟動時設置成我們自己的Bundle,這樣就可以做到,當使用時會調用這個方法. class Bundle: Foundation.Bundle { override func localizedString(forKey key: String, value: String?, table tableName: String?) -> String { if let bundle = AppSettings.shared.language.bundle { return bundle.localizedString(forKey: key, value: value, table: tableName) } else { return super.localizedString(forKey: key, value: value, table: tableName) } } } 

AppDelegate中


    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { object_setClass(Foundation.Bundle.main, Bundle.self) return true } 

使用

/// comment 是傳參, 假如你的value 中需要外界來決定內容,可以用%@,然后comment傳參. NSLocalizedString("key", comment: "") //切換語言時,只要設置就可以: AppSettings.shared.language = .English // .Chinese 

重置story

  • 對於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 } } } 


作者:Jason_風箏
鏈接:https://www.jianshu.com/p/e5d5fac05b8c
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM