设置 "AppleLanguages" 不会更改应用语言
Setting "AppleLanguages" doesn't change app language
我正在尝试实现一个可以更改应用程序语言的功能。
我试过这样设置:
let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject("de", forKey: "AppleLanguages")
应用重启后语言仍然是'system default'。
现在我通过设置 Scheme > Application Language > language
.
来测试不同的语言
但是是否可以让用户点击一个按钮并在重启后看到选择的语言?
此外,执行此操作以避免在重新启动时更改语言的正确方法是什么?
您可以在 AppDelegate.swift 中尝试以下操作,但更改不会立即出现,而是在您终止并重新启动您的应用程序后出现。 -
NSUserDefaults.standardUserDefaults().removeObjectForKey("AppleLanguages")
NSUserDefaults.standardUserDefaults().setObject(["de"], forKey: "AppleLanguages"
NSUserDefaults.standardUserDefaults().synchronize()
是的,您可以立即更改应用语言,例如,
var language = "de"
let path = NSBundle.mainBundle().pathForResource(language, ofType: "lproj")
let bundle = NSBundle(path: path!)
let string = bundle?.localizedStringForKey("key", value: nil, table: nil)
将您的 NSUserDefaults 值用于语言。
如果是为了测试目的,只需更改模拟器设置应用程序中的语言即可。
如果你想在你的应用程序中制作一种语言选择器,它很漂亮 painful 但我认为你不应该这样做。
您的应用程序从设备读取语言和区域设置并相应地更改 UI。
覆盖此行为很困难,您永远无法完成语言的完全更改,例如,如果您尝试显示地图在你的应用程序中,你的设备语言是西班牙语,但应用程序语言是英语,你会看到用西班牙语写的地图指示。
Here 一个可以提供帮助的项目。
以下是在 swift
-
中启动前如何更改语言
假设我想强制 Hebrew
本地化:
1。创建您自己的 Main.swift class
import Foundation
import UIKit
// Your initialization code here
let langCultureCode: String = "he_IL"
let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject([langCultureCode], forKey: "AppleLanguages")
defaults.synchronize()
UIApplicationMain(Process.argc, Process.unsafeArgv, nil, NSStringFromClass(AppDelegate))
2。删除您的 AppDelegate.swift "main" 责任
//@UIApplicationMain <-- COMMENT THIS OUT
class AppDelegate: UIResponder, UIApplicationDelegate
这将使您的应用在无需任何启动的情况下强制进入语言环境
您必须使用数组而不是字符串设置 AppleLanguages
键:
UserDefaults.standard.set(["de"], forKey: "AppleLanguages")
更新了@royherma 回答中提到的 main.swift
文件的 Swift 语法。这将避免在覆盖 UserDefaults 设置后必须重新启动应用程序:
import Foundation
import UIKit
// Your initialization code here
let langCultureCode: String = "LANGUAGE_CODE"
UserDefaults.standard.set([langCultureCode], forKey: "AppleLanguages")
UserDefaults.standard.synchronize()
UIApplicationMain(CommandLine.argc, CommandLine.unsafeArgv, nil, NSStringFromClass(AppDelegate.self))
与删除 AppDelegate.swift
文件中的 @UIApplicationMain
配对。
这个解决方案对我有用:
1.创建Bundle
的扩展
import Foundation
class L012Localizer: NSObject {
class func DoTheSwizzling() {
MethodSwizzleGivenClassName(cls: Bundle.self, originalSelector: #selector(Bundle.localizedString(forKey:value:table:)), overrideSelector:
#selector(Bundle.specialLocalizedString(key:value:table:)))
}
}
extension Bundle {
@objc func specialLocalizedString(key: String, value: String?, table tableName: String?) -> String {
let currentLanguage = Utils.currentLanguage().rawValue
var bundle = Bundle();
if currentLanguage != "" , let _path = Bundle.main.path(forResource: currentLanguage, ofType: "lproj") {
bundle = Bundle(path: _path)!
} else {
let _path = Bundle.main.path(forResource: "Base", ofType: "lproj")!
bundle = Bundle(path: _path)!
}
return (bundle.specialLocalizedString(key: key, value: value, table: tableName))
}
}
func MethodSwizzleGivenClassName(cls: AnyClass, originalSelector: Selector, overrideSelector: Selector){
let origMethod: Method = class_getInstanceMethod(cls, originalSelector)!;
let overrideMethod: Method = class_getInstanceMethod(cls, overrideSelector)!;
if (class_addMethod(cls, originalSelector, method_getImplementation(overrideMethod), method_getTypeEncoding(overrideMethod))) {
class_replaceMethod(cls, overrideSelector, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));
} else {
method_exchangeImplementations(origMethod, overrideMethod);
}
}
2. 在AppDelegate中调用DoTheSwizzling
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
L012Localizer.DoTheSwizzling()
return true
}
3. 创建语言实用程序
class Utils: NSObject {
class func setLanguage(_ lang: LanguageType) {
UserDefaults.standard.set([lang.rawValue], forKey: "AppleLanguages")
}
class func currentLanguage() -> LanguageType {
if let langs = UserDefaults.standard.object(forKey: "AppleLanguages") as? [String], let currentLang = langs.first {
return LanguageType(rawValue: currentLang) ?? .english
}
return .english
}
}
4.创建语言类型
enum LanguageType: String {
case english = "en"
case korea = "ko"
case vietnamese = "vi-VN"
func toString() -> String {
switch self {
case .korea:
return "Korea".localized
case .vietnamese:
return "Vietnamese".localized
default:
return "English".localized
}
}
}
5. 请记住,您必须将 Scheme 中的 Application Language 配置为 SystemLanguage
6. 然后每次需要本地化你的app,只需要调用即可。 Utils.setLanguage({语言类型})
我正在尝试实现一个可以更改应用程序语言的功能。
我试过这样设置:
let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject("de", forKey: "AppleLanguages")
应用重启后语言仍然是'system default'。
现在我通过设置 Scheme > Application Language > language
.
来测试不同的语言
但是是否可以让用户点击一个按钮并在重启后看到选择的语言?
此外,执行此操作以避免在重新启动时更改语言的正确方法是什么?
您可以在 AppDelegate.swift 中尝试以下操作,但更改不会立即出现,而是在您终止并重新启动您的应用程序后出现。 -
NSUserDefaults.standardUserDefaults().removeObjectForKey("AppleLanguages")
NSUserDefaults.standardUserDefaults().setObject(["de"], forKey: "AppleLanguages"
NSUserDefaults.standardUserDefaults().synchronize()
是的,您可以立即更改应用语言,例如,
var language = "de"
let path = NSBundle.mainBundle().pathForResource(language, ofType: "lproj")
let bundle = NSBundle(path: path!)
let string = bundle?.localizedStringForKey("key", value: nil, table: nil)
将您的 NSUserDefaults 值用于语言。
如果是为了测试目的,只需更改模拟器设置应用程序中的语言即可。
如果你想在你的应用程序中制作一种语言选择器,它很漂亮 painful 但我认为你不应该这样做。
您的应用程序从设备读取语言和区域设置并相应地更改 UI。
覆盖此行为很困难,您永远无法完成语言的完全更改,例如,如果您尝试显示地图在你的应用程序中,你的设备语言是西班牙语,但应用程序语言是英语,你会看到用西班牙语写的地图指示。
Here 一个可以提供帮助的项目。
以下是在 swift
-
假设我想强制 Hebrew
本地化:
1。创建您自己的 Main.swift class
import Foundation
import UIKit
// Your initialization code here
let langCultureCode: String = "he_IL"
let defaults = NSUserDefaults.standardUserDefaults()
defaults.setObject([langCultureCode], forKey: "AppleLanguages")
defaults.synchronize()
UIApplicationMain(Process.argc, Process.unsafeArgv, nil, NSStringFromClass(AppDelegate))
2。删除您的 AppDelegate.swift "main" 责任
//@UIApplicationMain <-- COMMENT THIS OUT
class AppDelegate: UIResponder, UIApplicationDelegate
这将使您的应用在无需任何启动的情况下强制进入语言环境
您必须使用数组而不是字符串设置 AppleLanguages
键:
UserDefaults.standard.set(["de"], forKey: "AppleLanguages")
更新了@royherma 回答中提到的 main.swift
文件的 Swift 语法。这将避免在覆盖 UserDefaults 设置后必须重新启动应用程序:
import Foundation
import UIKit
// Your initialization code here
let langCultureCode: String = "LANGUAGE_CODE"
UserDefaults.standard.set([langCultureCode], forKey: "AppleLanguages")
UserDefaults.standard.synchronize()
UIApplicationMain(CommandLine.argc, CommandLine.unsafeArgv, nil, NSStringFromClass(AppDelegate.self))
与删除 AppDelegate.swift
文件中的 @UIApplicationMain
配对。
这个解决方案对我有用:
1.创建Bundle
import Foundation
class L012Localizer: NSObject {
class func DoTheSwizzling() {
MethodSwizzleGivenClassName(cls: Bundle.self, originalSelector: #selector(Bundle.localizedString(forKey:value:table:)), overrideSelector:
#selector(Bundle.specialLocalizedString(key:value:table:)))
}
}
extension Bundle {
@objc func specialLocalizedString(key: String, value: String?, table tableName: String?) -> String {
let currentLanguage = Utils.currentLanguage().rawValue
var bundle = Bundle();
if currentLanguage != "" , let _path = Bundle.main.path(forResource: currentLanguage, ofType: "lproj") {
bundle = Bundle(path: _path)!
} else {
let _path = Bundle.main.path(forResource: "Base", ofType: "lproj")!
bundle = Bundle(path: _path)!
}
return (bundle.specialLocalizedString(key: key, value: value, table: tableName))
}
}
func MethodSwizzleGivenClassName(cls: AnyClass, originalSelector: Selector, overrideSelector: Selector){
let origMethod: Method = class_getInstanceMethod(cls, originalSelector)!;
let overrideMethod: Method = class_getInstanceMethod(cls, overrideSelector)!;
if (class_addMethod(cls, originalSelector, method_getImplementation(overrideMethod), method_getTypeEncoding(overrideMethod))) {
class_replaceMethod(cls, overrideSelector, method_getImplementation(origMethod), method_getTypeEncoding(origMethod));
} else {
method_exchangeImplementations(origMethod, overrideMethod);
}
}
2. 在AppDelegate中调用DoTheSwizzling
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
L012Localizer.DoTheSwizzling()
return true
}
3. 创建语言实用程序
class Utils: NSObject {
class func setLanguage(_ lang: LanguageType) {
UserDefaults.standard.set([lang.rawValue], forKey: "AppleLanguages")
}
class func currentLanguage() -> LanguageType {
if let langs = UserDefaults.standard.object(forKey: "AppleLanguages") as? [String], let currentLang = langs.first {
return LanguageType(rawValue: currentLang) ?? .english
}
return .english
}
}
4.创建语言类型
enum LanguageType: String {
case english = "en"
case korea = "ko"
case vietnamese = "vi-VN"
func toString() -> String {
switch self {
case .korea:
return "Korea".localized
case .vietnamese:
return "Vietnamese".localized
default:
return "English".localized
}
}
}
5. 请记住,您必须将 Scheme 中的 Application Language 配置为 SystemLanguage
6. 然后每次需要本地化你的app,只需要调用即可。 Utils.setLanguage({语言类型})