使用 Swift 强制 NSLocalizedString 使用特定语言

Force NSLocalizedString to use a specific language using Swift

使用 swift,我如何强制我的应用从特定 Localizable.strings.

读取数据

我在实例化 ViewController 之前将它放在 didFinishLaunchingWithOptions 中,但它仍然以英文显示应用程序。

NSUserDefaults.standardUserDefaults().removeObjectForKey("AppleLanguages")
NSUserDefaults.standardUserDefaults().setObject("fr", forKey: "AppleLanguages"   
NSUserDefaults.standardUserDefaults().synchronize()

我尝试像这样为 "AppleLanguages" 键传递一个数组,但它仍然不起作用:

NSUserDefaults.standardUserDefaults().setObject(["fr"], forKey: "AppleLanguages"

完成后,我可以在 App 中调用它并在不重新启动 App 的情况下考虑更改吗?

无法通过更改 AppleLanguages 的值立即更改应用程序的语言。需要重启应用才能生效。

看来您的问题是访问不同语言的本地化字符串而不是更改应用程序的语言,对吗?如果您希望您的应用程序支持多种语言,您可以只提供翻译并依靠 settings.app 进行实际更改。

如果您想从当前使用的本地化以外的地方访问本地化字符串,则需要访问正确的翻译包。然后只需查询该包的翻译。下面的一段代码应该可以解决问题。

let language = "en"
let path = Bundle.main.path(forResource: language, ofType: "lproj")
let bundle = Bundle(path: path!)
let string = bundle?.localizedStringForKey("key", value: nil, table: nil)

@Radu 由于@Markus 的原始回答,我也使它适用于 XCUITests:

您可以明确指定您的 MainBundle 的路径,它只适用于您的 Mac 模拟器,但它经常用于持续集成平台,所以这可能是可以接受的:

let language: String = "en"
let path = "/Users/{username}/{path_to_your_project}/\(language).lproj"
let bundle = Bundle(path: path)
let string = bundle?.localizedString(forKey: "key", value: nil, table: nil)

使用 NSLocalizedString 您可以指定捆绑包。

let language = "fr"
let path = Bundle.main.path(forResource: language, ofType: "lproj")!
let bundle = Bundle(path: path)!
let localizedString = NSLocalizedString(key, bundle: bundle, comment: "")

或者使用捆绑包,您也可以直接调用 localizedStringForKey:value:table:

在swift4中,我已经解决了,不用重启,不用库。 在尝试了很多选项之后,我找到了这个函数,您可以在其中传递要翻译的 stringToLocalize(属于 Localizable.String,字符串文件),以及要翻译的语言,以及它 returns 是字符串文件中该字符串的值:

    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!)!
    }
}

要从整个应用程序访问,并在其余 ViewController 的每个字符串中访问,而不是放置:

NSLocalizedString ("StringToLocalize", comment: “")

我已经替换成

let customLang = CustomLanguage() //declare at top

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

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