【问题标题】:Arrays of enums are enums in Swift?枚举数组是 Swift 中的枚举吗?
【发布时间】:2015-12-29 00:25:56
【问题描述】:

我正在关注Apple's Swift/iOS tutorial,它具有这行代码:

button.setImage( filledStarImage, forState: [UIControlState.Highlighted, UIControlState.Selected] )

但是UIButton.setImage的签名的定义是:

public func setImage(image: UIImage?, forState state: UIControlState)

没有接受[UIControlState]() 数组的setImage 重载。

显然有些巫术正在发生,谁能解释一下?

【问题讨论】:

    标签: swift cocoa-touch


    【解决方案1】:

    在 Swift 中,UIControlState 本身并不是一个枚举,而是一个结构。来自UIControl的语言参考:

    控制状态

    控件的状态;一个控件在某一时刻可以有多个状态 时间。根据控件的不同,状态的识别方式也不同。为了 例如,可以配置一个 UIButton 实例(使用 setImage:forState: 方法)来显示一个图像,当它在它的 正常状态和突出显示时的不同图像

    声明

    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 }
    }
    

    这里的关键是OptionSetType 协议(UIControlState 符合该协议),它允许我们对静态结构属性进行“类似枚举”的访问,因为它们有一个RawValue,即@ 987654330@。例如:

    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
    

    查看符合OptionsSetType 的实例方法(参见下面的语言参考链接)。除了成员管理(如上面的.contains(...);还有.remove(...).insert(..)),还可以使用union(...)intersect(...)等整洁的集合操作。

    总结一下; UIButton.setImage 签名要求forState state: UIControlState 是对的,但是由于OptionSetType 协议,看起来数组的[UIControlState.Highlighted, UIControlState.Selected] 实际上是调用结构类型参数UIControlState 的有效参数。

    还请注意,根据我上面的示例,结构名称可以省略,因此将 [.Highlighted, .Selected] 作为 forState 参数发送也可以。


    参考和好读物:

    【讨论】:

      【解决方案2】:

      UIControlState 符合 OptionSetType 协议,该协议为处理 BitwiseOperationsTypes 提供了方便的方法。因此,重载的不是 setImage,而是看起来像数组的东西。见https://developer.apple.com/library/ios/documentation/Swift/Reference/Swift_OptionSetType_Protocol/index.html#//apple_ref/swift/intf/s:PSs13OptionSetType

      【讨论】:

        猜你喜欢
        • 2020-10-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-05-18
        • 1970-01-01
        • 2023-03-26
        相关资源
        最近更新 更多