如何在 SwiftUI 中将 LocalizedStringKey 更改为 String

Posted

技术标签:

【中文标题】如何在 SwiftUI 中将 LocalizedStringKey 更改为 String【英文标题】:How to change LocalizedStringKey to String in SwiftUI 【发布时间】:2020-03-25 01:45:10 【问题描述】:

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

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

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

【问题讨论】:

我会以相反的顺序执行此操作,在任何地方存储/使用 String(因为它是模型),并且只在需要的地方创建 LocalizedStringKey(String)(因为它是 UI-only)。 @Asperi 我不明白。 MKAnnotation().title 的类型是 String,这就是问题所在。 【参考方案1】:

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! 

解决方法扩展,以及它如何工作的示例,以从 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`

现在我们有了字符串形式的键,你可以很容易地得到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
    

要了解这一点,请查看https://***.com/a/27879342/11837341

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

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


TL; DR(摘要)

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

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)
    

示例

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`

【讨论】:

【参考方案2】:

你可以使用 NSLocalizedString。

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

【讨论】:

与 SwiftUI 无关。 LocalizedStringKey 是一种类型。 我理解@jonye._.jin 的问题是他需要提供一个字符串,但他想以不同的语言显示标题/对其进行本地化。我知道这不是最初要求的演员阵容,但它解决了问题。最后有一个字符串的翻译。【参考方案3】:

为字符串添加扩展名以读取本地化语言

extension String 
    func localized() -> String 
        let path = Bundle.main.path(forResource: "your language", ofType: "lproj")!
        if let bundle = Bundle(path: path) 
            let str = bundle.localizedString(forKey: self, value: nil, table: nil)
            return str
        
        return ""
    

使用 LocalizedStringKey 加载示例代码

let title: String = "LocalizedStringKey".localized()

【讨论】:

与 SwiftUI 无关。 LocalizedStringKey 是一种类型。

以上是关于如何在 SwiftUI 中将 LocalizedStringKey 更改为 String的主要内容,如果未能解决你的问题,请参考以下文章

如何在 SwiftUI 中将 TabView 与 NavigationView 一起使用?

如何在 SwiftUI 中将模糊效果作为背景?

如何在 SwiftUI 中将 LocalizedStringKey 更改为 String

如何在 SwiftUI 中将图像设置为按钮?

如何在 SwiftUI 中将内容添加到收藏列表?

如何在 Userdefaults (SwiftUI) 中将新元素附加到数组