2014-09-27 6 views
68

Ich habe dies für-in-Schleife:Typ Gießen in for-Schleife in

for button in view.subviews { 
} 

Jetzt möchte ich Knopf in eine eigene Klasse geworfen werden, damit ich seine Eigenschaften verwenden.

Ich versuchte dies: for button in view.subviews as AClass

Aber es funktioniert nicht und gibt mir eine Fehlermeldung: 'AClass' does not conform to protocol 'SequenceType'

Und ich versuchte dies: for button:AClass in view.subviews

Aber tut weder, dass die Arbeit.

+0

Wie wäre es 'für Button in viewviews als [AClass]' – vacawama

+2

haha ​​Ich dachte nicht daran, natürlich ist es besser, das Array in ein Array von AClass zu werfen, danke Mann. Sie können eine Antwort darauf machen, damit ich Ihnen etwas Rep geben kann :) – Arbitur

+0

Vergleichen http://stackoverflow.com/questions/25097958/loop-through-subview-to-check-for-empty-uitextfield-swift/25098005# 25098005. –

Antwort

85

Für Swift 2 und später:

Swift 2 fügt Fall Muster-für Loops, die es noch einfacher und sicherer macht Guss in einem für Schleife eingeben:

for case let button as AClass in view.subviews { 
    // do something with button 
} 

Warum ist das besser als das, was Sie tun könnten in Swift 1.2 und früher? Denn Fallmuster können Sie Ihren spezifischen Typ aus der Sammlung auswählen. Es entspricht nur dem Typ, nach dem Sie suchen. Wenn Ihr Array also eine Mischung enthält, können Sie nur mit einem bestimmten Typ arbeiten.

Zum Beispiel:

let array: [Any] = [1, 1.2, "Hello", true, [1, 2, 3], "World!"] 
for case let str as String in array { 
    print(str) 
} 

Ausgang:

Hello 
World! 

Für Swift 1.2:

In diesem Fall Sie werfen view.subviews und nicht button, so dass Sie muss es in die a rray des Typs Sie wollen:

for button in view.subviews as! [AClass] { 
    // do something with button 
} 

Hinweis: Wenn der zugrunde liegende Array-Typ nicht [AClass] ist, wird dies zum Absturz bringen. Das sagt Ihnen die ! auf as!. Wenn Sie nicht sicher über die Art sind, können Sie einen bedingten Guss verwenden as? zusammen mit optionaler Bindung 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 
    } 
} 

Für Swift 1.1 und früher:

for button in view.subviews as [AClass] { 
    // do something with button 
} 

Hinweis: Dies wird auch abstürze wenn die Untersichten nicht alle vom Typ AClass sind. Die oben aufgeführte sichere Methode funktioniert auch mit früheren Versionen von Swift.

+0

Nur eine Anmerkung für andere wie mich, die es zuerst nicht verstanden haben - der Klassenname muss genau wie in diesem Beispiel in '' '[]' '' Klammern gehen. Vielleicht ist es nur ich, aber ich dachte zuerst, dass es nur eine Formatierungswahl im Codebeispiel ist :) Ich nehme an, das liegt daran, dass wir in ein Array werfen. –

+0

@kmcgrady Seine '' Class '' sieht viel besser aus als 'Array '. – Arbitur

+0

Aus Neugier, gibt es eine Möglichkeit, mehrere Case-Anweisungen innerhalb der for-Schleife zu tun? E. G. wenn ich eine Sache mit Buttons machen will, eine andere mit Textfeldern? – RonLugge

1

Die Antwort von vacawama war in Swift 1.0 korrekt. Und funktioniert nicht mehr mit Swift 2.0.

Wenn Sie versuchen, erhalten Sie eine Fehlermeldung erhalten, ähnlich wie:

'[AnyObject]' is not convertible to '[AClass]';

In Swift 2.0 müssen Sie schreiben wie:

for button in view.subviews as! [AClass] 
{ 
} 
+2

imo dies könnte nur ein Kommentar zu vacawamas Antwort sein :) – Arbitur

+0

@Arbitur: Es ist egal. Es ist meine Entscheidung, ob es ein Kommentar oder eine Antwort sein soll. Meine Antwort passt zu allen von der SO-Community definierten Regeln. Also, ob Sie mögen oder nicht, ich werde es als Antwort posten. –

98

Diese Option ist sicherer:

for case let button as AClass in view.subviews { 
} 
+1

Hm, das wusste ich nicht, danke! – Arbitur

+3

Dies sollte die richtige Antwort IMO sein. –

+0

Das scheint die schönere Antwort zu sein, da es keine Gewalt gibt. – Patrick

3

Sie können auch eine where Klausel

verwenden
for button in view.subviews where button is UIButton { 
    ... 
} 
+4

Die Where-Klausel ist ein boolescher Schutz, aber sie gibt nicht den Typ von "button" innerhalb des Schleifenkörpers aus, was das Ziel der anderen Lösungen ist. Dies wird also nur den Schleifenkörper auf Elementen von 'viewviews' ausführen, die' UIButton's sind, aber z. B. nicht helfen. beim Aufruf von 'AClass'-spezifischen Methoden auf' button'. –

+0

@JohnWhitley Sie sind richtig, dass "wo" nur Wachen und nicht wirft. – edelaney05