我对UIControlState的运行方式感到有些困惑.具体来说,如果我看下面的例子:
sender.setTitle("NewTitle", for: UIControlState.normal)
Run Code Online (Sandbox Code Playgroud)
据我所知,这为Button的(发件人)正常状态设置了标题.我原以为.normal是UIControlState类型的Enum值,但是后来才知道它是一个带常量的结构.第一个问题:
其次,当我查看UIStateControl的文档时,我看到的只是"常量"的定义,例如:
static var normal: UIControlState
Run Code Online (Sandbox Code Playgroud)
第二/第三个问题:
为什么UIStateControl的"常量"用"var"定义而不是"let?"
UIControlState的静态属性如何定义为"UIControlState"类型?这不是递归的吗?
为什么UIControlState是结构而不是枚举?
UIControlState是根本不枚举.枚举是"OR"类型.
enum Foo {
case a, b, c
}
var f = Foo.a
f = .b
f = .c
Run Code Online (Sandbox Code Playgroud)
所以,在上面的例子中,f可以保存.a 或 .b 或 .c.
但事实并非如此UIControlState; 这是一个选项集.选项集可以包含一组一个或多个案例.因此它是一个"AND"类型,我们通常使用struct符合OptionSet协议的类型来实现它们.
struct Bar : OptionSet {
let rawValue: Int
// Note that the raw values are unique powers of two.
// Each bit represents a flag determining if a given case is present.
static let a = Bar(rawValue: 1) // 001
static let b = Bar(rawValue: 2) // 010
static let c = Bar(rawValue: 4) // 100
}
var b = Bar.a // .a but not .b or .c
b = [.a, .b] // .a and .b, but not .c
b = [.c, .a, .b] // .a and .b and .c
Run Code Online (Sandbox Code Playgroud)
所以,你可以在上面的例子中看到,b可以容纳任何一组.a,.b和.c.
那也是一样的UIControlState; 例如,我们可以谈论关注和突出显示的控制状态:
let controlState: UIControlState = [.highlighted, .focused]
Run Code Online (Sandbox Code Playgroud)
如果它是一个enum,我们只能谈论控件是否处于一个特定状态,例如仅突出显示或仅聚焦.但这不是一个正确的模型,因为控件可以同时处于多个不同的状态.
另外值得注意的是UIControlState,这个.normal案例相当于一组空的选项[]; 它表示"未突出显示或聚焦,或选择或禁用或......".
其次,当我查看UIStateControl的文档时,我看到的只是"常量"的定义,例如:
Run Code Online (Sandbox Code Playgroud)static var normal: UIControlState
那不太准确.UIControlState自动生成的Swift标头中的声明如下所示:
public struct UIControlState : OptionSet {
public init(rawValue: UInt)
public static var normal: UIControlState { get }
public static var highlighted: UIControlState { get } // used when UIControl isHighlighted is set
public static var disabled: UIControlState { get }
public static var selected: UIControlState { get } // flag usable by app (see below)
@available(iOS 9.0, *)
public static var focused: UIControlState { get } // Applicable only when the screen supports focus
public static var application: UIControlState { get } // additional flags available for application use
public static var reserved: UIControlState { get } // flags reserved for internal framework use
}
Run Code Online (Sandbox Code Playgroud)
你会{ get }在最后注意到.这意味着它们只是只读属性.它们的实际实现方式(作为let常量,var只读计算属性等)是一个纯粹的实现细节.
在这种情况下,UIControlState在UIKit中使用NS_OPTIONS宏定义,Swift 作为 OptionSet符合结构导入,每个选项值都是静态只读属性.
UIControlState的静态属性如何定义为"UIControlState"类型?这不是递归的吗?
不,它根本不是递归的.请记住,它们是static属性,因此只不过是命名空间的全局变量UIControlState(并且它们甚至不需要存储;它们可以被计算,但是,这又是一个实现细节).
如果它们是实例存储的属性,那么它确实是递归的.但他们不是.
| 归档时间: |
|
| 查看次数: |
443 次 |
| 最近记录: |