有很多关于本地化的一般性讨论,但到目前为止,我还没有发现任何一个解决了我的问题。
我使用的是Localizable.strings文件,然后是另一个包含名为LocalizationStrings的枚举的swift文件。在枚举中,我使用静态let语句,这样我就可以避免在各种文件中出现拼写错误。(每天都有更多的东西要翻译(
所有这些都能很好地工作,除非您有一个包含字符串插值的本地化字符串。此方案失败,因为您无法将枚举括在引号中,或者它将作为输入的字符串读回,而不是转换为枚举的实际值(这是预期的行为(。
当然,从等式中去掉枚举并使用字符串插值效果很好,但我非常想知道是否有办法继续使用枚举值,即使存在字符串插值。
这里有一些代码可以解释:
Localizable.strings
"MY_NAME %@" = "My name is %@";
"YOUR_NAME" = "Your name is Fred";
LocalizationString.swift
enum LocalizationString {
static let myName: LocalizedStringKey = "MY_NAME %@"
static let yourName: LocalizedStringKey = "YOUR_NAME"
}
ContentView
struct CA_EmailVerifyView: View {
let name = "Tom"
var body: some View {
VStack {
// This works
Text(LocalizationString.yourName)
// This works (not using the enum)
Text("myName (name)")
// This does not work (won't compile, but this is how I would love to use it)
Text(LocalizationString.myName (name))
// This does not work (output is LocalizationString.myName Tom)
Text("LocalizationString.myName (name)")
}
}
}
这行得通吗?
enum LocalizationString {
static func myName(_ name: String) -> String {
String(format: NSLocalizedString("MY_NAME", comment: "My Name"), name)
}
static let yourName: LocalizedStringKey = "YOUR_NAME"
}
var name = "Nobody"
Text(LocalizationString. myName(name))
另一种可能性是对CustomStringConvertible或CVarArg类型使用扩展:
enum LocalizationString {
static let myName: String = "MY_NAME"
static let yourName: LocalizedStringKey = "YOUR_NAME"
}
extension String {
func format(_ str: CustomStringConvertible) -> String {
String(format: NSLocalizedString(self, comment: self), "(str)")
}
func formatArg(_ arg: CVarArg) -> String {
String(format: NSLocalizedString(self, comment: self), arg)
}
}
var name = "Nobody"
var other = 500
Text(LocalizationString.myName.format(name))
Text(LocalizationString.myName.formatArg(name))
Text(LocalizationString.myName.format(other))
Text(LocalizationString.myName.formatArg(other))
另一个使用%:
enum LocalizationString {
static let myName: String = "MY_NAME"
}
extension String {
static func %(_ key: String, _ arg: CVarArg) -> String {
String(format: NSLocalizedString(key, comment: key), arg)
}
}
var name = "Nobody"
var other = 500
Text(LocalizationString.myName % name)
Text(LocalizationString.myName % other)
编辑:对于多个参数,请使用一个数组和参数:格式的:
static func %(_ key: String, _ arg: [CVarArg]) -> String {
String(format: NSLocalizedString(key, comment: key), arguments: arg)
}
Text(LocalizationString.myName % [other, name])
编辑:使用LOcalizedStringKey:
extension LocalizedStringKey {
// [how-to-change-localizedstringkey-to-string-in-swiftui](https://stackoverflow.com/questions/60841915/how-to-change-localizedstringkey-to-string-in-swiftui)
var stringKey: String {
let description = "(self)"
let components = description.components(separatedBy: "key: "")
.map { $0.components(separatedBy: "",") }
return components[1][0]
}
static func %(_ key: LocalizedStringKey, _ arg: [CVarArg]) -> String {
String(format: NSLocalizedString(key.stringKey, comment: key.stringKey), arguments: arg)
}
static func %(_ key: LocalizedStringKey, _ arg: CVarArg) -> String {
String(format: NSLocalizedString(key.stringKey, comment: key.stringKey), arg)
}
}
enum LocalizationString {
static let myName: LocalizedStringKey = "MY_NAME"
static let yourName: LocalizedStringKey = "YOUR_NAME"
}
var name = "Nobody"
var other = 500
Text(LocalizationString.myName % name)
Text(LocalizationString.myName % [other, name])
我在swiftui 中找到了如何将本地化的字符串键更改为字符串的字符串键
答案比编写扩展和做复杂的工作简单得多。当存在变量时,您可以编写一个静态函数,而不是编写静态let。这一切都发生在LocalizationString.swift文件的枚举中,看起来像这样:
static func testText(name: String) -> LocalizedStringKey { LocalizedStringKey("TEST_TEXT (name)") }
在您的视图中使用此选项:
Text(LocalizationStrings.testTest(name: varname))
如果您需要更多的变量,只需将它们添加到函数中即可。