Swinner中的枚举是枚举吗? [英] Arrays of enums are enums in Swift?
问题描述
我正在关注 Apple's Swift / iOS教程,它具有以下代码行:
button.setImage (filledStarImage,forState:[UIControlState.Highlighted,UIControlState.Selected])
c $ c> UIButton.setImage 的签名是:
public func setImage(image:UIImage ?,forState state:UIControlState)
没有重载 setImage
接受
[UIControlState]()
数组。
显然有些voodoo正在进行,可以任何人解释?
在Swift中, UIControlState
本身不是枚举,但实际上是一个结构。从 UIControl
的语言参考:
控制状态
控制的状态;一个控件在
时间可以有多个状态。各国根据控制情况有所不同。对于
示例,可以配置一个UIButton实例(使用
setImage:forState:方法),以便在处于
正常状态时显示一个图像,
<$> c $ c> struct UIControlState:OptionSetType {
init(rawValue rawValue:UInt)
static var正常:UIControlState {get}
static var Highlighted:UIControlState {get}
static var禁用:UIControlState {get}
static var选择:UIControlState {get}
static var Focused:UIControlState {get}
static var应用程序:UIControlState {get}
static var保留: UIControlState {get}
}
OptionSetType
协议( UIControlState
符合),这允许我们对结构属性,因为它们具有 RawValue
,即 BitwiseOperationsType
。例如:
struct MyStruct:OptionSetType {
private var value:UInt
var rawValue:UInt {return self.value}
init(rawValue value:UInt){self.value = value}
static var正常:MyStruct {return self.init(rawValue:1& }
static var Highlighted:MyStruct {return self.init(rawValue:1 << 1)}
static var Disable:MyStruct {return self.init(rawValue:1& }
// ...
}
let MyOptionsA:MyStruct = [MyStruct.Normal,MyStruct.Disable]
let MyOptionsB:MyStruct = [.Normal, .Disable]
MyOptionsB.contains(.Highlighted)// false
MyOptionsB.contains(.Normal)// true
查看符合 OptionsSetType
的实例方法(请参阅下面的链接到语言ref)。此外,成员管理(例如 .contains(...)
如上所述;还有 .remove(...)
, .insert(..)
),整齐的操作如 union(...)
c $ c> intersect(...)也可用。
所以总结一下;你是对的, UIButton.setImage
签名要求 forState状态:UIControlState
,但是,由于 OptionSetType
协议,数组查找 [UIControlState.Highlighted,UIControlState.Selected]
实际上是调用结构类型的有效参数参数 UIControlState
。
请注意,根据上面的示例,结构名称可以省略,因此发送 [。Highlighted,.Selected] code> as
forState
参数会一样好。
参考&好的阅读:
- OptionSetType协议语言参考
- 如何在Swift 2中枚举OptionSetType?
- http://www.informit.com/articles/article.aspx?p=2420231
ul>
I'm following Apple's Swift/iOS tutorial and it features this line of code:
button.setImage( filledStarImage, forState: [UIControlState.Highlighted, UIControlState.Selected] )
But the definition of UIButton.setImage
's signature is:
public func setImage(image: UIImage?, forState state: UIControlState)
There is no overload of setImage
that accepts an [UIControlState]()
array.
Obviously some voodoo is going on, can anyone explain?
In Swift, the UIControlState
is not, per se, an enum, but actually a structure. From the language reference for UIControl
:
Control State
The state of a control; a control can have more than one state at a time. States are recognized differently depending on the control. For example, a UIButton instance may be configured (using the setImage:forState: method) to display one image when it is in its normal state and a different image when it is highlighted.
Declaration
struct UIControlState : OptionSetType { init(rawValue rawValue: UInt) static var Normal: UIControlState { get } static var Highlighted: UIControlState { get } static var Disabled: UIControlState { get } static var Selected: UIControlState { get } static var Focused: UIControlState { get } static var Application: UIControlState { get } static var Reserved: UIControlState { get } }
The key here is the OptionSetType
protocol (to which UIControlState
conforms), which allows us to do "enum-like" access to the static structures properties, given that these have a RawValue
that is a BitwiseOperationsType
. E.g.:
struct MyStruct : OptionSetType {
private var value: UInt
var rawValue: UInt { return self.value }
init(rawValue value: UInt) { self.value = value }
static var Normal: MyStruct { return self.init(rawValue: 1 << 0) }
static var Highlighted: MyStruct { return self.init(rawValue: 1 << 1) }
static var Disable: MyStruct { return self.init(rawValue: 1 << 2) }
// ...
}
let MyOptionsA : MyStruct = [MyStruct.Normal, MyStruct.Disable]
let MyOptionsB : MyStruct = [.Normal, .Disable]
MyOptionsB.contains(.Highlighted) // false
MyOptionsB.contains(.Normal) // true
Have a look at the instance methods (see link to language ref below) made available by conforming to the OptionsSetType
. In addition membership management (e.g. .contains(...)
as above; also, .remove(...)
, .insert(..)
), neat set operations such as union(...)
and intersect(...)
are also available.
So to summarize; you are right that the UIButton.setImage
signature asks for forState state: UIControlState
, but, due to the OptionSetType
protocol, the array-looking [UIControlState.Highlighted, UIControlState.Selected]
is in fact a valid argument for call to structure type parameter UIControlState
.
Note also, as per my example above, that the structure name can be left out, so sending [.Highlighted, .Selected]
as forState
argument would be just as fine.
Reference & good reads:
- OptionSetType Protocol Language Reference
- How do you enumerate OptionSetType in Swift 2?
- http://www.informit.com/articles/article.aspx?p=2420231
这篇关于Swinner中的枚举是枚举吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!