在iPhone上NSLocalizedString返回iPhone语言的字符串。 是否有可能强制NSLocalizedString使用特定语言来拥有应用程序 用不同的语言吗?


当前回答

对于Swift,你可以覆盖main.swift文件,并在应用程序运行之前设置UserDefaults字符串。这样你就不需要重新启动应用程序就能看到想要的效果。

import Foundation
import UIKit

// Your initialisation 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。

其他回答

简而言之:

本地化应用程序

你要做的第一件事就是用至少两种语言(本例中是英语和法语)来本地化你的应用程序。

覆盖NSLocalizedString

在你的代码中,不是使用NSLocalizedString(key, comment),而是使用一个宏MYLocalizedString(key, comment),定义如下: #定义MYLocalizedString(key, comment) [[MYLocalizationSystem sharedInstance] localizedStringForKey:(key) value:(comment)];

这个MYLocalizationSystem单例将:

通过设置正确的本地化NSBundle用户请求来设置语言 根据之前设置的语言返回本地化的NSString

设置用户语言

当用户在法语中更改应用程序语言时,调用[[MYLocalizationSystem sharedInstance] setLanguage:@"fr"];

- (void)setLanguage:(NSString *)lang
{
    NSString *path = [[NSBundle mainBundle] pathForResource:lang ofType:@"lproj"];
    if (!path)
    {
        _bundle = [NSBundle mainBundle];
        NSLog(@"Warning: No lproj for %@, system default set instead !", lang);
        return;
    }

    _bundle = [NSBundle bundleWithPath:path];
}

在这个例子中,这个方法将本地化的bundle设置为fr.lproj

返回本地化字符串

一旦你设置了本地化的bundle,你就可以通过下面的方法从他那里得到正确的本地化字符串:

- (NSString *)localizedStringForKey:(NSString *)key value:(NSString *)value
{
    // bundle was initialized with [NSBundle mainBundle] as default and modified in setLanguage method
    return [self.bundle localizedStringForKey:key value:value table:nil];
}

希望这对你有所帮助。

您可以在NSWinery.io的这篇文章中找到更多详细信息

在swift 4中,我已经解决了它,不需要重新启动或使用库。

在尝试了许多选项之后,我找到了这个函数,其中传递Localizable的stringToLocalize(。字符串文件)你想要翻译的,以及你想要翻译的语言,它返回的是你在strings文件中拥有的String的值:

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
let bundleLanguage = customLang.createBundle()

NSLocalizedString("StringToLocalize", tableName: nil, bundle: bundleLanguage, value: "", comment: “”) //use in each String

我不知道这是否是最好的方法,但我发现它非常简单,而且对我有用,我希望它能帮助到你!

NSLocalizedString() reads the value for the key AppleLanguages from the standard user defaults ([NSUserDefaults standardUserDefaults]). It uses that value to choose an appropriate localization among all existing localizations at runtime. When Apple builds the user defaults dictionary at app launch, they look up the preferred language(s) key in the system preferences and copy the value from there. This also explains for example why changing the language settings in OS X has no effect on running apps, only on apps started thereafter. Once copied, the value is not updated just because the settings change. That's why iOS restarts all apps if you change then language.

但是,用户默认字典的所有值都可以被命令行参数覆盖。请参阅NSArgumentDomain上的NSUserDefaults文档。这甚至包括那些从应用程序首选项(.plist)文件加载的值。如果您只是为了测试而更改一个值,了解这一点非常有用。

所以如果你想改变语言只是为了测试,你可能不想改变你的代码(如果你忘记删除这段代码…),而是告诉Xcode用一个命令行参数启动你的应用程序(例如使用西班牙语本地化):

根本不需要修改代码。只需为不同的语言创建不同的方案,您可以快速启动应用程序一次在一种语言和一次在另一种只需切换方案。

通过从应用程序中选择特定语言来使用特定语言的技巧是强制NSLocalizedString使用特定的bundle,这取决于所选的语言,

这是我为此写的一篇文章 学习ios应用的高级本地化

这是ios应用程序中一个示例应用程序的高级本地化代码

你觉得Swift 3的这个解决方案怎么样?

extension String {

    func localized(forLanguage language: String = Locale.preferredLanguages.first!.components(separatedBy: "-").first!) -> String {

        guard let path = Bundle.main.path(forResource: language == "en" ? "Base" : language, ofType: "lproj") else {

            let basePath = Bundle.main.path(forResource: "Base", ofType: "lproj")!

            return Bundle(path: basePath)!.localizedString(forKey: self, value: "", table: nil)
        }

        return Bundle(path: path)!.localizedString(forKey: self, value: "", table: nil)
    }
}

简单的用法:

"report".localized(forLanguage: "pl") //forced language
"report".localized() //default language selected by user in settings, in case when your app doesnt support selected lanaguage, the default one is selected, here is an english.