Wenn meine App zu ihrem Root-View-Controller zurückkehrt, muss viewDidAppear:
ich bei der Methode alle Unteransichten entfernen.
Wie kann ich das machen?
Edit: Mit Dank an Cocoafan : Diese Situation wird durch die Tatsache durcheinander gebracht , dass NSView
und UIView
Dinge anders zu behandeln. Für NSView
(nur Desktop-Mac-Entwicklung) können Sie einfach Folgendes verwenden:
[someNSView setSubviews:[NSArray array]];
Für UIView
(nur iOS-Entwicklung) können Sie sicher verwenden, makeObjectsPerformSelector:
da die subviews
Eigenschaft eine Kopie des Arrays von Unteransichten zurückgibt:
[[someUIView subviews]
makeObjectsPerformSelector:@selector(removeFromSuperview)];
Vielen Dank an Tommy für den Hinweis, dass makeObjectsPerformSelector:
das subviews
Array während der Aufzählung geändert zu werden scheint (wofür es funktioniert NSView
, aber nicht für UIView
).
Bitte lesen Sie diese SO-Frage für weitere Details.
Hinweis: Wenn Sie eine dieser beiden Methoden verwenden, werden alle in Ihrer Hauptansicht enthaltenen Ansichten entfernt und freigegeben , sofern sie nicht an anderer Stelle beibehalten werden. Aus der Apple-Dokumentation zu removeFromSuperview :
Wenn die Übersicht des Empfängers nicht Null ist, gibt diese Methode den Empfänger frei. Wenn Sie die Ansicht wiederverwenden möchten, müssen Sie sie beibehalten, bevor Sie diese Methode aufrufen, und sie nach Bedarf freigeben, wenn Sie damit fertig sind oder nachdem Sie sie einer anderen Ansichtshierarchie hinzugefügt haben.
UIView
eine Kopie dessubviews
veränderlichen Arrays zurück, sodass dieser Code einfach funktioniert. Ganz andere Geschichte auf dem Desktop, bei der derselbe Code eine Ausnahme auslöst. Siehe stackoverflow.com/questions/4665179/…someUIView.Subviews.All( v => { v.RemoveFromSuperview(); return true; } );
. IMHO Reiniger zu sagen, was Sie meinen :someUIView.Subviews.ToList().ForEach( v => v.RemoveFromSuperview() );
.Holen Sie sich alle Unteransichten von Ihrem Root-Controller und senden Sie jeweils eine removeFromSuperview:
quelle
self.view
wie du.for (UIView *v in [self.view subviews])
es ist einfacherIn Swift können Sie einen funktionalen Ansatz wie den folgenden verwenden:
Zum Vergleich würde der imperative Ansatz folgendermaßen aussehen:
Diese Codefragmente funktionieren jedoch nur unter iOS / tvOS . Unter macOS sieht das etwas anders aus.
quelle
(subviews as [UIView]).map { $0.removeFromSuperview() }
.map
. Dies ist eine reine Nebenwirkung und wird besser so gehandhabt:view.subviews.forEach() { $0.removeFromSuperview() }
Wenn Sie alle Unteransichten in Ihrem UIView (hier
yourView
) entfernen möchten , schreiben Sie diesen Code auf Ihre Schaltfläche:quelle
Dies gilt nur für OSX, da unter iOS eine Kopie des Arrays aufbewahrt wird
Wenn Sie alle Unteransichten entfernen, empfiehlt es sich, am Ende des Arrays mit dem Löschen zu beginnen und das Löschen so lange fortzusetzen, bis Sie den Anfang erreicht haben. Dies kann mit diesen beiden Codezeilen erreicht werden:
SWIFT 1.2
oder (weniger effizient, aber besser lesbar)
HINWEIS
Sie sollten die Unteransichten NICHT in normaler Reihenfolge entfernen, da dies zu einem Absturz führen kann, wenn eine UIView-Instanz gelöscht wird, bevor die
removeFromSuperview
Nachricht an alle Objekte des Arrays gesendet wurde. (Das Löschen des letzten Elements würde natürlich keinen Absturz verursachen.)Daher der Code
sollte NICHT verwendet werden.
Zitat aus der Apple-Dokumentation zu makeObjectsPerformSelector :
(was für diesen Zweck die falsche Richtung wäre)
quelle
removeFromSuperview
der Vorgang abgeschlossen ist, wird die UIView aus dem Array entfernt. Wenn keine anderen lebenden Instanzen mit einer starken Beziehung zur UIView vorhanden sind, wird die UIView ebenfalls gelöscht. Dies kann zu einer Out-of-Bound-Ausnahme führen.[yourView subviews]
eine KOPIE des Arrays zurück und ist daher sicher. (Beachten Sie, dass unter OSX das, was Sie sagen, korrekt ist.)Versuchen Sie es auf diese Weise schnell 2.0
quelle
forEach
basierte Lösung wurde nach Ihrer hinzugefügt, das habe ich verpasst. Entschuldigung.Verwenden Sie den folgenden Code, um alle Unteransichten zu entfernen.
quelle
Verwenden der Swift-
UIView
Erweiterung:quelle
Erstellen Sie in Ziel-C eine Kategoriemethode aus der UIView-Klasse.
quelle
quelle
So entfernen Sie alle Unteransichten Syntax:
Verwendungszweck :
Diese Methode ist in der Datei NSArray.h vorhanden und verwendet die NSArray-Schnittstelle (NSExtendedArray)
quelle
Wenn Sie Swift verwenden, ist dies so einfach wie:
Es ist in der Philosophie dem
makeObjectsPerformSelector
Ansatz ähnlich , jedoch mit etwas mehr Typensicherheit.quelle
map
sollte nicht zu Nebenwirkungen führen. Außerdem kann das gleiche Ergebnis über erzielt werdenforEach
.Für ios6 mit Autolayout musste ich ein wenig Code hinzufügen, um auch die Einschränkungen zu entfernen.
Ich bin mir sicher, dass es einen besseren Weg gibt, dies zu tun, aber es hat bei mir funktioniert. In meinem Fall konnte ich kein Direct verwenden,
[tagview removeConstraints:tagview.constraints]
da in XCode Einschränkungen festgelegt wurden, die gelöscht wurden.quelle
In monotouch / xamarin.ios hat das bei mir funktioniert:
quelle
So entfernen Sie alle Unteransichten aus den Übersichten:
quelle
iCount++
undiCount--
den Index der gleiche verlassen, so dass es eine Endlosschleife , wenn sein wird[oSubView count]>0
. Dies ist definitiv fehlerhaft und NICHT VERWENDBAR .