我有这个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
但这也不起作用。
对于Swift 2及更高版本:
Swift 2为for循环添加了case模式,这使得在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]
,则会崩溃。这就是!
上的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。
此选项更安全:
for case let button as AClass in view.subviews {
}
或者很敏捷的方式:
view.subviews
.compactMap { $0 as AClass }
.forEach { .... }
您也可以使用where
子句
for button in view.subviews where button is UIButton {
...
}
vacawama提供的答案在Swift 1.0中是正确的。并且不再适用于Swift 2.0。
如果您尝试,您将收到类似于以下内容的错误:
'[AnyObject]'不能转换为'[A Class]';
在Swift 2.0中,您需要编写如下:
for button in view.subviews as! [AClass]
{
}
提供的答案是正确的,我只是想添加它作为补充。
当使用强制转换的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
// ...
}
如果数组的某些元素(但不是全部)可能是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 {
// ...
}