在Swift中枚举类型非常强大,内置的实现可以大大减少我们手敲的代码量.下面碰巧就有这么一个需求:Person类里面有一个type属性,其值包含2个内容,一个是name,类型为String,另一个是logo,类型也为字符串,不过表现为绘文字emoji.
因为结构或类的静态属性都可以用点访问符来直接访问,所以我们可以轻易写出如下代码:
class Person{
struct type{
static let big = ("big","��")
static let med = ("med","��")
static let tin = ("tin","✂️")
}
var type:(String,String)?
}
let p = Person()
p.type = Person.type.big
print(p.type!.1)
貌似浏览器不完全支持emoji编码,不过请你相信我那些绿色中间带着问号的菱形在Xcode里都是漂亮的emoji字符 ;)
这样实现非常轻便,也是一种选择.不过作为Swift中自带的enum来说貌似更符合这样的场合,于是我们尝试写出如下代码,虽然是错误的:
class Person{
enum type:(String,String) {
case big = ("big","xxx")
case med = ("med","xxx")
case tin = ("tin","xxx")
}
}
不过编译器该抗议了!他会告诉你enum的raw类型有误!
这样是不可以的哦!不过Swift给我对enum类型自定义扩展的一种方法,就是实现RawRepresentable协议!
为了遵守该协议你必须实现3个东东:
1.typealias RawValue = 你需要的类型
2.rawValue的计算属性
3.初始化器init?(rawValue:)
下面我们再假想一个场景:一个记录中包含一个type,用来说明记录类型,与上面类似,每一个类型都有name和logo两部分.我们可以选择自定义一个结构来搞定:
struct Type_t{
var name:String
var logo:String
}
不过在这里,使用元组更为简单,以下是完整的实现:
private enum TypeName:String{
case longTerm = "LongTerm"
case targeted = "Targeted"
case allTheTime = "AllTheTime"
case critical = "Critical"
case urgent = "Urgent"
}
enum type:RawRepresentable{
case longTerm,targeted,allTheTime,critical,urgent
static let allTypes:[type] = [.longTerm,.targeted,.allTheTime,.critical,.urgent]
typealias RawValue = (name:String,logo:String)
var rawValue: (name:String,logo:String){
switch self{
case .longTerm:
return (TypeName.longTerm.rawValue,"��")
case .targeted:
return (TypeName.targeted.rawValue,"��")
case .allTheTime:
return (TypeName.allTheTime.rawValue,"��")
case .critical:
return (TypeName.critical.rawValue,"��")
case .urgent:
return (TypeName.urgent.rawValue,"⏰")
}
}
init?(rawValue: type.RawValue) {
switch rawValue.name{
case TypeName.longTerm.rawValue:
self = .longTerm
case TypeName.targeted.rawValue:
self = .targeted
case TypeName.allTheTime.rawValue:
self = .allTheTime
case TypeName.critical.rawValue:
self = .critical
case TypeName.urgent.rawValue:
self = .urgent
default:
return nil
}
}
}
于是乎如果我们想要用type来初始化UI,我们可以这么写:
var idx = 0
KsMain.type.allTypes.forEach {type in
if type != .longTerm{
ksTypeSeg.setTitle(type.rawValue.1,forSegmentAt: idx)
idx += 1
}
}
效果如下: