如何在 SwiftUI 中将 LocalizedStringKey 更改为 String

jon*_*jin 9 xcode ios swift swiftui

我正在尝试使用 SwiftUI 本地化 AppleMapView 中显示的标记。

但是,MKAnnotation 的标记标题的类型固定为String。而且我不想继承或创建自定义类,因为它太麻烦了。

我需要的只是将 LocalizedStringKey 转换为 String来设置标记的标题。这有什么帮助吗?

Raf*_*urt 34

您可以简单地使用以下方法来做到这一点:String(localized: "YOUR_LOCALIZED_KEY")

如果您的本地化密钥是以编程方式生成的,则必须将其存储在符合“LocalizationValue”的变量中,如下所示:

let localizedKey = String.LocalizationValue(stringLiteral: yourLocalizedVar)

然后您可以使用它String(localized: localizedKey)来获取本地化的文本内容。

Mahdi BM 的解决方案有一个问题,因为即使您使用西班牙语、葡萄牙语等多种语言的变体,Swift 也只返回语言代码。这两个示例的语言代码将始终返回 ES 和 PT,但具有本地化键的文件夹名称会有所不同:PT 可以是“pt-PT”或“pt-BR”,西班牙语可以是“es”或“es” -419'(拉丁美洲),这些情况将导致您的应用程序崩溃。获取此引用的区域设置也是一个糟糕的主意,因为它由当前语言和区域组成,两者都可以来自不同的地方,例如,如果用户来自日本但在美国,则用户的区域设置很可能是 jp_US@日语日历。

  • 它适用于 iOS15+。iOS 14 有原生方法吗? (4认同)
  • 问题是如何将 LocalizedStringKey 类型的值转换为字符串,而不是将字符串文字转换为字符串。我们怎样才能以比 Mahdi BM 更安全的方式做到前者呢? (2认同)

mat*_*thr 7

您可以使用 NSLocalizedString。

let localizedString = NSLocalizedString("LOCALIZED-STRING-KEY", comment: "Describe what is being localized here")
Run Code Online (Sandbox Code Playgroud)

  • 我理解@jonye._.jin 的问题,因为他需要提供一个字符串,但他想以不同的语言显示标题/本地化它。我知道这不是最初要求的演员阵容,但它解决了问题。最后有一个字符串翻译。 (10认同)
  • 与 SwiftUI 无关。LocalizedStringKey 是一种类型。 (8认同)

Mah*_* BM 7

LocalizedStringKey有一个名为的成员key,其中包含与本地化文件中的本地化字符串相对应的键字符串。不幸的是,我们无法直接访问密钥,因此我们需要解决获取密钥的方法。

// An Example that won't work:
let localizedKey = LocalizedStringKey.init("SOME_LOCALIZED_KEY_HERE")

localizedKey.key // ERRROOOOORR! `key` is an internal member of `LocalizedStringKey` and you can't access it! 
Run Code Online (Sandbox Code Playgroud)

解决方法扩展以及它如何工作的示例,以从 LocalizedStringKey 中获取密钥:

extension LocalizedStringKey {
// imagine `self` is equal to LocalizedStringKey("KEY_HERE")

    var stringKey: String {
        let description = "\(self)"
// in this example description will be `LocalizedStringKey(key: "KEY_HERE", hasFormatting: false, arguments: [])`
// for more clarity, `let description = "\(self)"` will have no differences
// compared to `let description = "\(LocalizedStringKey(key: "KEY_HERE", hasFormatting: false, arguments: []))"` in this example.

        let components = description.components(separatedBy: "key: \"")
            .map { $0.components(separatedBy: "\",") }
// here we separate the string by its components. 
// in `LocalizedStringKey(key: "KEY_HERE", hasFormatting: false, arguments: [])`
// our key lays between two strings which are `key: "` and `",`.
// if we manage to get what is between `key: "` and `",`, that would be our Localization Key
// which in this example is `KEY_HERE`

        return components[1][0]
// by trial, we know that `components[1][0]` will always be our localization Key
// which is `KEY_HERE` in this example.
    }

// An Example:
let localizedKey = LocalizedStringKey("KEY_HERE")
print(localizedKey.stringkey)
// prints `KEY_HERE`
Run Code Online (Sandbox Code Playgroud)

现在我们将键作为字符串,您可以轻松获取 LocalizedStringKey 的键所指向的本地化字符串。

extension String {
    static func localizedString(for key: String,
                                locale: Locale = .current) -> String {
        
        let language = locale.languageCode
        let path = Bundle.main.path(forResource: language, ofType: "lproj")!
        let bundle = Bundle(path: path)!
        let localizedString = NSLocalizedString(key, bundle: bundle, comment: "")
        
        return localizedString
    }
}
Run Code Online (Sandbox Code Playgroud)

要了解这一点,请查看/sf/answers/1951553971/

现在您可以轻松地将 LocalizedStringKey 的值转换为字符串:

extension LocalizedStringKey {
func stringValue(locale: Locale = .current) -> String {
        return .localizedString(for: self.stringKey, locale: locale)
    }
}

Run Code Online (Sandbox Code Playgroud)

TL; 博士(摘要)

将这些扩展添加到您的项目中:

extension LocalizedStringKey {
    var stringKey: String {
        let description = "\(self)"

        let components = description.components(separatedBy: "key: \"")
            .map { $0.components(separatedBy: "\",") }

        return components[1][0]
    }
}

extension String {
    static func localizedString(for key: String,
                                locale: Locale = .current) -> String {
        
        let language = locale.languageCode
        let path = Bundle.main.path(forResource: language, ofType: "lproj")!
        let bundle = Bundle(path: path)!
        let localizedString = NSLocalizedString(key, bundle: bundle, comment: "")
        
        return localizedString
    }
}

extension LocalizedStringKey {
    func stringValue(locale: Locale = .current) -> String {
        return .localizedString(for: self.stringKey, locale: locale)
    }
}
Run Code Online (Sandbox Code Playgroud)

例子

let localizedKey = LocalizedStringKey("KEY_NAME_HERE")

print(localizedKey.stringKey)
//prints `KEY_NAME_HERE`

print(localizedKey.stringValue())
// prints Localized value of `KEY_NAME_HERE`
// DOESNT print `KEY_NAME_HERE`
Run Code Online (Sandbox Code Playgroud)

  • 对于每个偶然发现这个答案的人,请查看@rafael-bitencourt 的本机解决方案。它就像 `String(localized: "YOUR_LOCALIZED_KEY")` 一样简单 (3认同)