Antworten:
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 des subviews
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:
NSArray *viewsToRemove = [self.view subviews];
for (UIView *v in viewsToRemove) {
[v removeFromSuperview];
}
self.view
wie du.
for (UIView *v in [self.view subviews])
es ist einfacher
In Swift können Sie einen funktionalen Ansatz wie den folgenden verwenden:
view.subviews.forEach { $0.removeFromSuperview() }
Zum Vergleich würde der imperative Ansatz folgendermaßen aussehen:
for subview in view.subviews {
subview.removeFromSuperview()
}
Diese Codefragmente funktionieren jedoch nur unter iOS / tvOS . Unter macOS sieht das etwas anders aus.
(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:
[[yourView subviews] makeObjectsPerformSelector: @selector(removeFromSuperview)];
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:
for (int i=mySuperView.subviews.count-1; i>=0; i--)
[[mySuperView.subviews objectAtIndex:i] removeFromSuperview];
SWIFT 1.2
for var i=mySuperView.subviews.count-1; i>=0; i-- {
mySuperView.subviews[i].removeFromSuperview();
}
oder (weniger effizient, aber besser lesbar)
for subview in mySuperView.subviews.reverse() {
subview.removeFromSuperview()
}
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
[[someUIView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
sollte NICHT verwendet werden.
Zitat aus der Apple-Dokumentation zu makeObjectsPerformSelector :
Sendet an jedes Objekt im Array die von einem bestimmten Selektor identifizierte Nachricht, beginnend mit dem ersten Objekt und weiter durch das Array bis zum letzten Objekt.
(was für diesen Zweck die falsche Richtung wäre)
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
view.subviews.forEach { $0.removeFromSuperview() }
forEach
basierte Lösung wurde nach Ihrer hinzugefügt, das habe ich verpasst. Entschuldigung.
Verwenden Sie den folgenden Code, um alle Unteransichten zu entfernen.
for (UIView *view in [self.view subviews])
{
[view removeFromSuperview];
}
So entfernen Sie alle Unteransichten Syntax:
- (void)makeObjectsPerformSelector:(SEL)aSelector;
Verwendungszweck :
[self.View.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
Diese Methode ist in der Datei NSArray.h vorhanden und verwendet die NSArray-Schnittstelle (NSExtendedArray)
Wenn Sie Swift verwenden, ist dies so einfach wie:
subviews.map { $0.removeFromSuperview }
Es ist in der Philosophie dem makeObjectsPerformSelector
Ansatz ähnlich , jedoch mit etwas mehr Typensicherheit.
map
sollte nicht zu Nebenwirkungen führen. Außerdem kann das gleiche Ergebnis über erzielt werden forEach
.
Für ios6 mit Autolayout musste ich ein wenig Code hinzufügen, um auch die Einschränkungen zu entfernen.
NSMutableArray * constraints_to_remove = [ @[] mutableCopy] ;
for( NSLayoutConstraint * constraint in tagview.constraints) {
if( [tagview.subviews containsObject:constraint.firstItem] ||
[tagview.subviews containsObject:constraint.secondItem] ) {
[constraints_to_remove addObject:constraint];
}
}
[tagview removeConstraints:constraints_to_remove];
[ [tagview subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
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.
In monotouch / xamarin.ios hat das bei mir funktioniert:
SomeParentUiView.Subviews.All(x => x.RemoveFromSuperview);
So entfernen Sie alle Unteransichten aus den Übersichten:
NSArray *oSubView = [self subviews];
for(int iCount = 0; iCount < [oSubView count]; iCount++)
{
id object = [oSubView objectAtIndex:iCount];
[object removeFromSuperview];
iCount--;
}
iCount++
und iCount--
den Index der gleiche verlassen, so dass es eine Endlosschleife , wenn sein wird [oSubView count]>0
. Dies ist definitiv fehlerhaft und NICHT VERWENDBAR .