我有这个for-in循环:
for button in view.subviews {
}
现在,我希望将按钮强制转换为自定义类,以便可以使用其属性。
我尝试了这个: for button in view.subviews as AClass
但是它不起作用,给我一个错误:'AClass' does not conform to protocol 'SequenceType'
我尝试了这个: for button:AClass in view.subviews
但是,这也不起作用。
我有这个for-in循环:
for button in view.subviews {
}
现在,我希望将按钮强制转换为自定义类,以便可以使用其属性。
我尝试了这个: for button in view.subviews as AClass
但是它不起作用,给我一个错误:'AClass' does not conform to protocol 'SequenceType'
我尝试了这个: for button:AClass in view.subviews
但是,这也不起作用。
Answers:
对于Swift 2和更高版本:
Swift 2 在for循环中添加了大小写模式,这使得在for循环中进行类型转换更加容易和安全:
for case let button as AClass in view.subviews {
// do something with button
}
为什么这比您在Swift 1.2和更早版本中可以做的更好?因为案例模式允许您从集合中选择特定类型。它仅与您要查找的类型匹配,因此,如果数组包含混合,则只能对特定类型进行操作。
例如:
let array: [Any] = [1, 1.2, "Hello", true, [1, 2, 3], "World!"]
for case let str as String in array {
print(str)
}
输出:
Hello World!
对于Swift 1.2:
在这种情况下,您正在转换,view.subviews而不是button,因此您需要将其向下转换为所需类型的数组:
for button in view.subviews as! [AClass] {
// do something with button
}
注意:如果基础数组类型不是[AClass],则将崩溃。那就是!on as!告诉你的。如果不确定类型,可以使用条件转换as?和可选绑定if let:
if let subviews = view.subviews as? [AClass] {
// If we get here, then subviews is of type [AClass]
for button in subviews {
// do something with button
}
}
对于Swift 1.1和更早版本:
for button in view.subviews as [AClass] {
// do something with button
}
注意:如果子视图的类型不是全部,这也会崩溃AClass。上面列出的安全方法也适用于早期版本的Swift。
[Class]看起来比更好Array<Class>。
您还可以使用where子句
for button in view.subviews where button is UIButton {
...
}
button循环体内的类型,这是其他解决方案的目标。因此,这只能在元素上运行的循环体view.subviews,其是UIButtonS,但不利于例如,在调用AClass的特异性方法button。
where只有警卫而没有演员。
where对于仅需要布尔值守卫的情况(可能是双关语),可能会更优雅,更易读。
所提供的答案是正确的,我只想将此添加为补充。
在强制转换中使用for循环时,代码将崩溃(正如其他人已经提到的那样)。
for button in view.subviews as! [AClass] {
// do something with button
}
但与其使用if子句,
if let subviews = view.subviews as? [AClass] {
// If we get here, then subviews is of type [AClass]
...
}
另一种方法是使用while循环:
/* If you need the index: */
var iterator = view.subviews.enumerated().makeIterator()
while let (index, subview) = iterator.next() as? (Int, AClass) {
// Use the subview
// ...
}
/* If you don't need the index: */
var iterator = view.subviews.enumerated().makeIterator()
while let subview = iterator.next().element as? AClass {
// Use the subview
// ...
}
如果数组的某些元素(但不是全部)可能是type,这似乎更方便AClass。
尽管目前(从Swift 5开始),我还是进行了for-case循环:
for case let (index, subview as AClass) in view.subviews.enumerated() {
// ...
}
for case let subview as AClass in view.subviews {
// ...
}
for button in view.subviews as [AClass]