你好我试图在不重新启动应用程序的情况下更改本地化字符串文件,更改语言后,我需要重新启动应用程序以查看新语言,这就是我正在更改应用程序语言的方式,但是我需要重新启动应用程序才能查看更改这个图书馆 https://github.com/marmelroy/Localize-Swift我需要以编程方式设置所有标签值,这让我头疼,我不想这样
var selectedLanguage:Languages
let preferredLanguage : String = Bundle.main.preferredLocalizations.first!
print("app langugage \(preferredLanguage)")
if(preferredLanguage == "en") {
// Localize.setCurrentLanguage("de")
selectedLanguage = .de
LanguageManger.shared.setLanguage(language: selectedLanguage)
}
else {
// Localize.setCurrentLanguage("en")
selectedLanguage = .en
LanguageManger.shared.setLanguage(language: selectedLanguage)
}
LanguageManger.shared.setLanguage(language: selectedLanguage)
// return to root view contoller and reload it
let transition: UIViewAnimationOptions = .transitionFlipFromLeft
let rootviewcontroller: UIWindow = ((UIApplication.shared.delegate?.window)!)!
rootviewcontroller.rootViewController = self.storyboard?.instantiateViewController(withIdentifier: "rootnav")
let mainwindow = (UIApplication.shared.delegate?.window!)!
mainwindow.backgroundColor = UIColor(hue: 0.6477, saturation: 0.6314, brightness: 0.6077, alpha: 0.8)
UIView.transition(with: mainwindow, duration: 0.55001, options: transition, animations: { () -> Void in
}) { (finished) -> Void in
}
答案 0 :(得分:1)
创建一个新的类NSBundle + Language.h,NSBundle + Language.m。并且不要忘记添加桥接头。
NSBundle + Language.h
#import <Foundation/Foundation.h>
@interface NSBundle (Language)
+(void)setLanguage:(NSString*)language;
@end
NSBundle + Language.m
#import "NSBundle+Language.h"
#import <objc/runtime.h>
static const char _bundle=0;
@interface BundleEx: NSBundle
@end
@implementation BundleEx
-(NSString*)localizedStringForKey:(NSString *)key value:(NSString *)value table:(NSString *)tableName
{
NSBundle* bundle=objc_getAssociatedObject(self, &_bundle);
return bundle ? [bundle localizedStringForKey:key value:value table:tableName]: [super localizedStringForKey:key value:value table:tableName];
}
@end
@implementation NSBundle (Language)
+(void)setLanguage:(NSString*)language
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^
{
object_setClass([NSBundle mainBundle],[BundleEx class]);
});
objc_setAssociatedObject([NSBundle mainBundle], &_bundle, language ? [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:language ofType:@"lproj"]]: nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end
之后,使用此语言管理器更改语言:-
class LanguageManager: NSObject {
//MARK: Set language preference
class func setSelectedLanguage(dictionary: [String: String]) {
let userDefaults = UserDefaults.standard
userDefaults.set(dictionary, forKey: kSelectedLanguageDetails)
userDefaults.synchronize()
}
class func getSelectedLanguage() -> [String: String]? {
let userDefaults = UserDefaults.standard
return userDefaults.value(forKey: kSelectedLanguageDetails) as? [String: String]
}
class func getSelectedLangaugeCode() -> String{
if let selectedLanguageDetails = LanguageManager.getSelectedLanguage() {
if let languageCode = selectedLanguageDetails[LocalizationKeys.kLanguageCode.rawValue] {
Bundle.setLanguage(LanguageManager.getAppleLanguageCode(languageCode: languageCode.lowercased()))
return languageCode.lowercased()
}
else {
let languageDetails = [LocalizationKeys.kLanguageCode.rawValue:"EN", LocalizationKeys.kLanguageName.rawValue:"English", LocalizationKeys.kLanguageID.rawValue:"1"]
LanguageManager.setSelectedLanguage(dictionary: languageDetails)
if let languageCode = languageDetails[LocalizationKeys.kLanguageCode.rawValue] {
Bundle.setLanguage(LanguageManager.getAppleLanguageCode(languageCode: languageCode.lowercased()))
return languageCode.lowercased()
}
}
}
else {
let languageDetails = [LocalizationKeys.kLanguageCode.rawValue:"EN", LocalizationKeys.kLanguageName.rawValue:"English", LocalizationKeys.kLanguageID.rawValue:"1"]
LanguageManager.setSelectedLanguage(dictionary: languageDetails )
if let languageCode = languageDetails[LocalizationKeys.kLanguageCode.rawValue] {
Bundle.setLanguage(LanguageManager.getAppleLanguageCode(languageCode: languageCode.lowercased()))
return languageCode.lowercased()
}
}
return "en"
}
/// Checks for the Language preferences selected by user
class func checkLanguagePreferenceAndSetToDefaults() {
if let selectedLanguageDetails = LanguageManager.getSelectedLanguage() {
if let languageCode = selectedLanguageDetails[LocalizationKeys.kLanguageCode.rawValue] {
Bundle.setLanguage(LanguageManager.getAppleLanguageCode(languageCode: languageCode.lowercased()))
}
else {
let languageDetails = [LocalizationKeys.kLanguageCode.rawValue:"EN", LocalizationKeys.kLanguageName.rawValue:"English", LocalizationKeys.kLanguageID.rawValue:"1"]
LanguageManager.setSelectedLanguage(dictionary: languageDetails)
if let languageCode = languageDetails[LocalizationKeys.kLanguageCode.rawValue] {
Bundle.setLanguage(LanguageManager.getAppleLanguageCode(languageCode: languageCode.lowercased()))
}
}
}
else {
let languageDetails = [LocalizationKeys.kLanguageCode.rawValue:"EN", LocalizationKeys.kLanguageName.rawValue:"English", LocalizationKeys.kLanguageID.rawValue:"1"]
LanguageManager.setSelectedLanguage(dictionary: languageDetails )
if let languageCode = languageDetails[LocalizationKeys.kLanguageCode.rawValue] {
Bundle.setLanguage(LanguageManager.getAppleLanguageCode(languageCode: languageCode.lowercased()))
}
}
}
//MARK: Get Language Code
/// Return apple specific language code
///
/// - parameter languageCode: language code string
///
/// - returns: apples language code
static func getAppleLanguageCode(languageCode:String) -> String{
switch languageCode.lowercased() {
case "en":
return "en"
case "es":
return "es"
case "fr":
return "fr"
case "de":
return "de"
case "it":
return "it"
default:
return languageCode
}
}
}
将语言选项定义如下:-
let KlanguageOptionArray: [[String:String]] = [
[
"LanguageCode": "EN",
"Name": "English",
"LanguageID": "1"
],
[
"LanguageCode": "ES",
"Name": "Español",
"LanguageID": "2"
],
[
"LanguageCode": "FR",
"Name": "Français",
"LanguageID": "3"
],
[
"LanguageCode": "DE",
"Name": "Deutsch",
"LanguageID": "4"
],
[
"LanguageCode": "IT",
"Name": "Italiano",
"LanguageID": "5"
]
]
使用以下代码更改所选语言
let selectedLanguageDetails = self.languageOptionArray[indexPath.row]
LanguageManager.setSelectedLanguage(dictionary: selectedLanguageDetails)
if let languageCode = selectedLanguageDetails[LocalizationKeys.kLanguageCode.rawValue] {
Bundle.setLanguage(LanguageManager.getAppleLanguageCode(languageCode: languageCode.lowercased()))
NotificationCenter.default.post(name: NSNotification.Name(rawValue: NotificationCenterTypes.ReloadTableOnLanguageChangeNotification), object: nil)
}
别忘了在每次启动时添加它
if let selectedLanguageDetails = LanguageManager.getSelectedLanguage() {
if let languageCode = selectedLanguageDetails[LocalizationKeys.kLanguageCode.rawValue] {
Bundle.setLanguage(LanguageManager.getAppleLanguageCode(languageCode: languageCode.lowercased()))
}
else {
}
}
希望这对您有帮助
答案 1 :(得分:0)
在Swift 4中,我无需重新启动或使用库即可解决该问题。 在尝试了许多选项之后,我发现了此函数,您在其中传递了要翻译的(Localizable.String,字符串文件的)stringToLocalize,要翻译的语言以及返回的值您在字符串文件中拥有的字符串:
func localizeString (stringToLocalize: String, language: String) -> String
{
let path = Bundle.main.path (forResource: language, ofType: "lproj")
let languageBundle = Bundle (path: path!)
return languageBundle! .localizedString (forKey: stringToLocalize, value: "", table: nil)
}
考虑到此功能,我在Swift文件中将其创建为全局文件:
struct CustomLanguage {
func createBundlePath () -> Bundle {
let selectedLanguage = //recover the language chosen by the user (in my case, from UserDefaults)
let path = Bundle.main.path(forResource: selectedLanguage, ofType: "lproj")
return Bundle(path: path!)!
}
}
要从整个应用程序以及其余ViewControllers的每个字符串中进行访问,而不是放置:
NSLocalizedString ("StringToLocalize", comment: “")
我已将其替换为
let customLang = CustomLanguage() //declare at top
NSLocalizedString("StringToLocalize", tableName: nil, bundle: customLang.createBundlePath(), value: "", comment: “”) //use in each String
我不知道这是否是最好的方法,但是我发现它非常简单,并且对我有用,希望对您有帮助!