我试图禁用一大组各种控件。如果数组是[Slider1,Slider 2,Slider 3]或任何其他一组匹配的UIControl,这可以正常工作。
let C = [Slider, Button, Label]
for control in C, {
control.enabled = B
}
返回错误" UIView类型的值没有成员'已启用'。"。 我假设当我混合UIcontrols类型时,它将数组类型化为UIView。
有没有办法让这项工作或其他同样有效的方法?
答案 0 :(得分:2)
您可以使UILabel
和UIControl
符合通用协议:
protocol HasEnabled : class {
var enabled: Bool { get set }
}
extension UILabel : HasEnabled { }
extension UIControl : HasEnabled { }
然后你可以声明一个HasEnabled
类型的数组:
let controls : [ HasEnabled ] = [ label, slider, button ]
for control in controls {
control.enabled = true
}
或者声明一个UIView
数组,但只对元素进行迭代
符合HasEnabled
:
let controls : [UIView] = [ label, slider, button ]
for case let control as HasEnabled in controls {
control.enabled = true
}
在第一种情况下,编译器确保只有对象
符合HasEnabled
的内容将添加到数组中。
在第二种情况下,可以添加任意UIView
个对象
数组,但循环体只为符合要求的人执行
到HasEnabled
。
答案 1 :(得分:1)
问题是Label
。虽然UILabel
有一个名为enabled
的成员,但与<{1}}和UISlider
的 成员不同。
正如你正确提到的那样,后来的那些继承自提供成员UIButton
的{{3}}。
然而enabled
没有。它恰好(恰巧)定义了一个名为UILabel
的成员。然而,编译器并不真正关心成员的命名。他寻找第一个普通的超类enabled
,它没有一个名为UIView
的成员,就是这样!
因此,您的解决方案是仅将数组中的实际enabled
组合在一起。文档列出了以下内容:
循环标签必须在不同/第二个循环中完成。