この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はcaseパターンを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の場合:
この場合は、button
ではなくview.subviews
をキャストしているため、目的の型の配列にダウンキャストする必要があります。
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]」は「[AClass]」に変換できません。
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]
...
}
もう1つの方法は、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 {
// ...
}