SwiftUI 本地化和枚举
SwiftUI Localization and Enums
有很多关于本地化的一般性讨论,但 none 我发现到目前为止已经解决了我的问题。
我正在使用一个 Localizable.strings 文件,然后是另一个 swift 文件,其中包含一个名为 LocalizationStrings 的枚举。在枚举中,我使用静态 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"
}
内容视图
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)
编辑:
对于多个参数,使用数组和 arguments: in format :
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](
var stringKey: String {
let description = "\(self)"
let components = description.components(separatedBy: "key: \"")
.map { [=14=].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])
我在 how-to-change-localizedstringkey-to-string-in-swiftui
中找到了 stringKey
答案比编写扩展和做复杂的工作要简单得多。当一个变量存在时,你可以写一个静态函数,而不是写一个静态 let。这一切都发生在 LocalizationString.swift 文件的枚举中,看起来像这样:
static func testText(name: String) -> LocalizedStringKey { LocalizedStringKey("TEST_TEXT \(name)") }
要在您的视图中使用它:
Text(LocalizationStrings.testTest(name: varname))
如果您需要更多变量,只需将它们添加到函数中即可。
有很多关于本地化的一般性讨论,但 none 我发现到目前为止已经解决了我的问题。
我正在使用一个 Localizable.strings 文件,然后是另一个 swift 文件,其中包含一个名为 LocalizationStrings 的枚举。在枚举中,我使用静态 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"
}
内容视图
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)
编辑: 对于多个参数,使用数组和 arguments: in format :
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](
var stringKey: String {
let description = "\(self)"
let components = description.components(separatedBy: "key: \"")
.map { [=14=].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])
我在 how-to-change-localizedstringkey-to-string-in-swiftui
中找到了 stringKey答案比编写扩展和做复杂的工作要简单得多。当一个变量存在时,你可以写一个静态函数,而不是写一个静态 let。这一切都发生在 LocalizationString.swift 文件的枚举中,看起来像这样:
static func testText(name: String) -> LocalizedStringKey { LocalizedStringKey("TEST_TEXT \(name)") }
要在您的视图中使用它:
Text(LocalizationStrings.testTest(name: varname))
如果您需要更多变量,只需将它们添加到函数中即可。