swift 中带有本地化字符串的枚举
Enum with localized string in swift
我想对本地化字符串使用枚举,所以我喜欢这个,它有效,但是
此解决方案的问题是:我无法从本地化字符串中轻松获取枚举值,我必须拥有执行此操作的密钥:
let option = DietWithoutResidueOption(rawValue: "NoDiet")
如果不是,我必须调用 dietWithoutResidueOptionWith 方法来获取枚举值...:/
有更好的解决方案来直接存储 localizedString 而不是枚举中的键?
谢谢
枚举
enum DietWithoutResidueOption: String {
case NoDiet = "NoDiet"
case ThreeDays = "ThreeDays"
case FiveDays = "FiveDays"
private func localizedString() -> String {
return NSLocalizedString(self.rawValue, comment: "")
}
static func dietWithoutResidueOptionWith(#localizedString: String) -> DietWithoutResidueOption {
switch localizedString {
case DietWithoutResidueOption.ThreeDays.localizedString():
return DietWithoutResidueOption.ThreeDays
case DietWithoutResidueOption.FiveDays.localizedString():
return DietWithoutResidueOption.FiveDays
default:
return DietWithoutResidueOption.NoDiet
}
}
}
Localizable.strings
"NoDiet" = "NON, JE N'AI PAS DE RÉGIME";
"ThreeDays" = "OUI, SUR 3 JOURS";
"FiveDays" = "OUI, SUR 5 JOURS";
通话
println(DietWithoutResidueOption.FiveDays.localizedString())
对于 enum
的 RawValue
类型,您可以使用任何 StringLiteralConvertible, Equatable
类型。
那么,怎么样:
import Foundation
struct LocalizedString: StringLiteralConvertible, Equatable {
let v: String
init(key: String) {
self.v = NSLocalizedString(key, comment: "")
}
init(localized: String) {
self.v = localized
}
init(stringLiteral value:String) {
self.init(key: value)
}
init(extendedGraphemeClusterLiteral value: String) {
self.init(key: value)
}
init(unicodeScalarLiteral value: String) {
self.init(key: value)
}
}
func ==(lhs:LocalizedString, rhs:LocalizedString) -> Bool {
return lhs.v == rhs.v
}
enum DietWithoutResidueOption: LocalizedString {
case NoDiet = "NoDiet"
case ThreeDays = "ThreeDays"
case FiveDays = "FiveDays"
var localizedString: String {
return self.rawValue.v
}
init?(localizedString: String) {
self.init(rawValue: LocalizedString(localized: localizedString))
}
}
使用它,您可以通过 3 种方式构造 DietWithoutResidueOption
:
let option1 = DietWithoutResidueOption.ThreeDays
let option2 = DietWithoutResidueOption(rawValue: "ThreeDays") // as Optional
let option3 = DietWithoutResidueOption(localizedString: "OUI, SUR 3 JOURS") // as Optional
并提取本地化字符串:
let localized = option1.localizedString
其他选择:
枚举
enum Title : String {
case CEO = "CEOKey"
case CTO = "CTOKey"
case CFO = "CFOKey"
private static let allTitles = [CEO, CTO, CFO]
var localizedString: String {
return NSLocalizedString(self.rawValue, comment: "")
}
init!(rawValue: String) {
var keys = Title.allTitles
var filtered = keys.filter { [=10=].rawValue == rawValue }
self = filtered.first!
}
init!(localizedString: String) {
var keys = Title.allTitles
var filtered = keys.filter { [=10=].localizedString == localizedString }
self = filtered.first!
}
}
Localizable.strings
"CEOKey" = "Chief Executive Officer";
"CTOKey" = "Chief Technical Officer";
"CFOKey" = "Chief Financial Officer";
合约枚举:
let option1 = Title.CFO
let option2 = Title(rawValue: "CTOKey") // init from key
let option3 = Title(localizedString: NSLocalizedString("CEOKey", comment: "")) // init from value
提取本地化字符串:
println("option1 localized string : \(option1.localizedString)")
println("option2 localized string : \(option2.localizedString)")
println("option3 localized string : \(option3.localizedString)")
输入
option1 localized string : Chief Financial Officer
option2 localized string : Chief Technical Officer
option3 localized string : Chief Executive Officer
如果未找到本地化字符串或键,此代码将生成异常
试试这个,非常简单直接:
enum ChoicesTitle: String {
case choice1 = "Choice 1"
case choice2 = "Choice 2"
case choice3 = "Choice 3"
case choice4 = "Choice 4"
case choice5 = "Choice 5"
case choice6 = "Choice 6"
func localizedString() -> String {
return NSLocalizedString(self.rawValue, comment: "")
}
static func getTitleFor(title:ChoicesTitle) -> String {
return title.localizedString()
}
}
你可以这样使用它:
let stringOfChoice1: String = ChoicesTitle.getTitleFor(title: .choice1)
希望这对你有用
一个不错的方法是创建一个具有静态变量的可本地化字符串结构,如下所示:
LocalizableStrings.swift
struct LocalizableStrings {
static let noDiet = NSLocalizedString("NoDiet", comment: "")
static let threeDays = NSLocalizedString("ThreeDays", comment: "")
static let fiveDays = NSLocalizedString("FiveDays", comment: "")
}
Localizable.strings
"NoDiet" = "NON, JE N'AI PAS DE RÉGIME";
"ThreeDays" = "OUI, SUR 3 JOURS";
"FiveDays" = "OUI, SUR 5 JOURS";
你的枚举看起来像这样:
枚举
enum DietWithoutResidueOption {
case NoDiet,
ThreeDays,
FiveDays
var description : String {
get {
switch(self) {
case .NoDiet:
return LocalizableStrings.noDiet
case .ThreeDays:
return LocalizableStrings.threeDays
case .FiveDays:
return LocalizableStrings.fiveDays
}
}
}
}
因此,例如,要获取您的描述,您可以执行以下操作:
DietWithoutResidueOption.NoDiet.description
这种方法的好处是您将可本地化字符串的键放在一个文件中。因此,例如,如果您更改 Localizable.strings 文件上的 NoDiet 键,您只需要更新 LocalizableStrings.swift 文件,而不是我们拥有的所有地方NoDiet 键作为字符串。此外,
你冒着拼错 NoDiet 键的风险避免这种情况,因为您的代码将无法编译,并且您会看到一条错误消息,说明错误所在。
试试我创建的这个协议,你可以导入,像下面这样使用它。
https://github.com/Wei18/ZWExt/blob/master/ZWExt/Classes/Protocol/Localizable.swift
enum SomeKey: String, Localizable {
case MenuGreeting = "lb_menu_greeting"
case HaveBook = "I have %@ books"
}
// Sample
let menuGreeting: String = SomeKey.MenuGreeting.localized()
let iHaveBoxes: String = SomeKey.HaveBook.localized([3])
/*
// You also can make it with html.
SomeKey.CustomCase.localizedHTML()
SomeKey.CustomCase.localizedHTML([])
*/
这是一个迟到的答案,但我刚刚与 Apple 工程师讨论了他们建议这样做的主题:
enum LocalizedStrings {
case title
var localized: String {
switch self {
case .title:
return NSLocalizedString("My Title", comment: "My Comment")
}
}
}
在您的情况下,解决方案与原始代码没有太大区别:
enum DietWithoutResidueOption {
case NoDiet
case ThreeDays
case FiveDays
var localizedString: String {
switch self {
case .NoDiet:
return NSLocalizedString("NoDiet", comment: "Some comment")
case .ThreeDays:
return NSLocalizedString("ThreeDays", comment: "Some comment")
case .FiveDays:
return NSLocalizedString("FiveDays", comment: "Some comment")
}
}
static func dietWithoutResidueOptionWith(localizedString: String) -> DietWithoutResidueOption {
switch localizedString {
case DietWithoutResidueOption.ThreeDays.localizedString:
return DietWithoutResidueOption.ThreeDays
case DietWithoutResidueOption.FiveDays.localizedString:
return DietWithoutResidueOption.FiveDays
default:
return DietWithoutResidueOption.NoDiet
}
}
}
原因是他们不希望您将变量传递给 NSLocalizedString()。这与优化和解析字符串有关。想象一下 Xcode 在某个时刻自己生成 localizable.strings 文件,但它找不到字符串,因为它们是作为变量传递的。
这是我的例子
enum Localization: String {
case appName = "app_name"
case appOk = "app_ok"
case appError = "app_error"
case placeholderNoContent = "placeholder_no_content"
case homeTitle = "home_title"
public func localized(args: CVarArg...) -> String {
let localizedString = NSLocalizedString(self.rawValue, comment: "")
return withVaList(args, { (args) -> String in
return NSString(format: localizedString, locale: Locale.current, arguments: args) as String
})
}
}
用法
self.homeTitleLabel = Localization.homeTitle.localized()
此本地化枚举可轻松用于字符串格式。
我想对本地化字符串使用枚举,所以我喜欢这个,它有效,但是 此解决方案的问题是:我无法从本地化字符串中轻松获取枚举值,我必须拥有执行此操作的密钥:
let option = DietWithoutResidueOption(rawValue: "NoDiet")
如果不是,我必须调用 dietWithoutResidueOptionWith 方法来获取枚举值...:/
有更好的解决方案来直接存储 localizedString 而不是枚举中的键?
谢谢
枚举
enum DietWithoutResidueOption: String {
case NoDiet = "NoDiet"
case ThreeDays = "ThreeDays"
case FiveDays = "FiveDays"
private func localizedString() -> String {
return NSLocalizedString(self.rawValue, comment: "")
}
static func dietWithoutResidueOptionWith(#localizedString: String) -> DietWithoutResidueOption {
switch localizedString {
case DietWithoutResidueOption.ThreeDays.localizedString():
return DietWithoutResidueOption.ThreeDays
case DietWithoutResidueOption.FiveDays.localizedString():
return DietWithoutResidueOption.FiveDays
default:
return DietWithoutResidueOption.NoDiet
}
}
}
Localizable.strings
"NoDiet" = "NON, JE N'AI PAS DE RÉGIME";
"ThreeDays" = "OUI, SUR 3 JOURS";
"FiveDays" = "OUI, SUR 5 JOURS";
通话
println(DietWithoutResidueOption.FiveDays.localizedString())
对于 enum
的 RawValue
类型,您可以使用任何 StringLiteralConvertible, Equatable
类型。
那么,怎么样:
import Foundation
struct LocalizedString: StringLiteralConvertible, Equatable {
let v: String
init(key: String) {
self.v = NSLocalizedString(key, comment: "")
}
init(localized: String) {
self.v = localized
}
init(stringLiteral value:String) {
self.init(key: value)
}
init(extendedGraphemeClusterLiteral value: String) {
self.init(key: value)
}
init(unicodeScalarLiteral value: String) {
self.init(key: value)
}
}
func ==(lhs:LocalizedString, rhs:LocalizedString) -> Bool {
return lhs.v == rhs.v
}
enum DietWithoutResidueOption: LocalizedString {
case NoDiet = "NoDiet"
case ThreeDays = "ThreeDays"
case FiveDays = "FiveDays"
var localizedString: String {
return self.rawValue.v
}
init?(localizedString: String) {
self.init(rawValue: LocalizedString(localized: localizedString))
}
}
使用它,您可以通过 3 种方式构造 DietWithoutResidueOption
:
let option1 = DietWithoutResidueOption.ThreeDays
let option2 = DietWithoutResidueOption(rawValue: "ThreeDays") // as Optional
let option3 = DietWithoutResidueOption(localizedString: "OUI, SUR 3 JOURS") // as Optional
并提取本地化字符串:
let localized = option1.localizedString
其他选择:
枚举
enum Title : String {
case CEO = "CEOKey"
case CTO = "CTOKey"
case CFO = "CFOKey"
private static let allTitles = [CEO, CTO, CFO]
var localizedString: String {
return NSLocalizedString(self.rawValue, comment: "")
}
init!(rawValue: String) {
var keys = Title.allTitles
var filtered = keys.filter { [=10=].rawValue == rawValue }
self = filtered.first!
}
init!(localizedString: String) {
var keys = Title.allTitles
var filtered = keys.filter { [=10=].localizedString == localizedString }
self = filtered.first!
}
}
Localizable.strings
"CEOKey" = "Chief Executive Officer";
"CTOKey" = "Chief Technical Officer";
"CFOKey" = "Chief Financial Officer";
合约枚举:
let option1 = Title.CFO
let option2 = Title(rawValue: "CTOKey") // init from key
let option3 = Title(localizedString: NSLocalizedString("CEOKey", comment: "")) // init from value
提取本地化字符串:
println("option1 localized string : \(option1.localizedString)")
println("option2 localized string : \(option2.localizedString)")
println("option3 localized string : \(option3.localizedString)")
输入
option1 localized string : Chief Financial Officer
option2 localized string : Chief Technical Officer
option3 localized string : Chief Executive Officer
如果未找到本地化字符串或键,此代码将生成异常
试试这个,非常简单直接:
enum ChoicesTitle: String {
case choice1 = "Choice 1"
case choice2 = "Choice 2"
case choice3 = "Choice 3"
case choice4 = "Choice 4"
case choice5 = "Choice 5"
case choice6 = "Choice 6"
func localizedString() -> String {
return NSLocalizedString(self.rawValue, comment: "")
}
static func getTitleFor(title:ChoicesTitle) -> String {
return title.localizedString()
}
}
你可以这样使用它:
let stringOfChoice1: String = ChoicesTitle.getTitleFor(title: .choice1)
希望这对你有用
一个不错的方法是创建一个具有静态变量的可本地化字符串结构,如下所示:
LocalizableStrings.swift
struct LocalizableStrings {
static let noDiet = NSLocalizedString("NoDiet", comment: "")
static let threeDays = NSLocalizedString("ThreeDays", comment: "")
static let fiveDays = NSLocalizedString("FiveDays", comment: "")
}
Localizable.strings
"NoDiet" = "NON, JE N'AI PAS DE RÉGIME";
"ThreeDays" = "OUI, SUR 3 JOURS";
"FiveDays" = "OUI, SUR 5 JOURS";
你的枚举看起来像这样:
枚举
enum DietWithoutResidueOption {
case NoDiet,
ThreeDays,
FiveDays
var description : String {
get {
switch(self) {
case .NoDiet:
return LocalizableStrings.noDiet
case .ThreeDays:
return LocalizableStrings.threeDays
case .FiveDays:
return LocalizableStrings.fiveDays
}
}
}
}
因此,例如,要获取您的描述,您可以执行以下操作:
DietWithoutResidueOption.NoDiet.description
这种方法的好处是您将可本地化字符串的键放在一个文件中。因此,例如,如果您更改 Localizable.strings 文件上的 NoDiet 键,您只需要更新 LocalizableStrings.swift 文件,而不是我们拥有的所有地方NoDiet 键作为字符串。此外, 你冒着拼错 NoDiet 键的风险避免这种情况,因为您的代码将无法编译,并且您会看到一条错误消息,说明错误所在。
试试我创建的这个协议,你可以导入,像下面这样使用它。
https://github.com/Wei18/ZWExt/blob/master/ZWExt/Classes/Protocol/Localizable.swift
enum SomeKey: String, Localizable {
case MenuGreeting = "lb_menu_greeting"
case HaveBook = "I have %@ books"
}
// Sample
let menuGreeting: String = SomeKey.MenuGreeting.localized()
let iHaveBoxes: String = SomeKey.HaveBook.localized([3])
/*
// You also can make it with html.
SomeKey.CustomCase.localizedHTML()
SomeKey.CustomCase.localizedHTML([])
*/
这是一个迟到的答案,但我刚刚与 Apple 工程师讨论了他们建议这样做的主题:
enum LocalizedStrings {
case title
var localized: String {
switch self {
case .title:
return NSLocalizedString("My Title", comment: "My Comment")
}
}
}
在您的情况下,解决方案与原始代码没有太大区别:
enum DietWithoutResidueOption {
case NoDiet
case ThreeDays
case FiveDays
var localizedString: String {
switch self {
case .NoDiet:
return NSLocalizedString("NoDiet", comment: "Some comment")
case .ThreeDays:
return NSLocalizedString("ThreeDays", comment: "Some comment")
case .FiveDays:
return NSLocalizedString("FiveDays", comment: "Some comment")
}
}
static func dietWithoutResidueOptionWith(localizedString: String) -> DietWithoutResidueOption {
switch localizedString {
case DietWithoutResidueOption.ThreeDays.localizedString:
return DietWithoutResidueOption.ThreeDays
case DietWithoutResidueOption.FiveDays.localizedString:
return DietWithoutResidueOption.FiveDays
default:
return DietWithoutResidueOption.NoDiet
}
}
}
原因是他们不希望您将变量传递给 NSLocalizedString()。这与优化和解析字符串有关。想象一下 Xcode 在某个时刻自己生成 localizable.strings 文件,但它找不到字符串,因为它们是作为变量传递的。
这是我的例子
enum Localization: String {
case appName = "app_name"
case appOk = "app_ok"
case appError = "app_error"
case placeholderNoContent = "placeholder_no_content"
case homeTitle = "home_title"
public func localized(args: CVarArg...) -> String {
let localizedString = NSLocalizedString(self.rawValue, comment: "")
return withVaList(args, { (args) -> String in
return NSString(format: localizedString, locale: Locale.current, arguments: args) as String
})
}
}
用法
self.homeTitleLabel = Localization.homeTitle.localized()
此本地化枚举可轻松用于字符串格式。