Risposte:
Edit: Si ringrazia cocoafan : Questa situazione è confusa dal fatto che NSView
e UIView
cose maniglia in modo diverso. Per NSView
(solo sviluppo desktop Mac), puoi semplicemente utilizzare quanto segue:
[someNSView setSubviews:[NSArray array]];
Per UIView
(solo sviluppo iOS), puoi tranquillamente utilizzarlo makeObjectsPerformSelector:
perché la subviews
proprietà restituirà una copia dell'array di sottoview:
[[someUIView subviews]
makeObjectsPerformSelector:@selector(removeFromSuperview)];
Grazie a Tommy per aver sottolineato che makeObjectsPerformSelector:
sembra modificare l' subviews
array mentre viene elencato (cosa che fa per NSView
, ma non per UIView
).
Si prega di consultare questa domanda SO per maggiori dettagli.
Nota: l' utilizzo di uno di questi due metodi rimuoverà tutte le viste contenute nella vista principale e le rilascerà , se non vengono conservate altrove. Dalla documentazione di Apple su removeFromSuperview :
Se la superview del ricevitore non è nulla, questo metodo rilascia il ricevitore. Se si prevede di riutilizzare la vista, assicurarsi di conservarla prima di chiamare questo metodo e di rilasciarla nel modo appropriato al termine o dopo averla aggiunta a un'altra gerarchia di viste.
UIView
restituisce una copia della subviews
matrice mutevole, quindi questo codice funziona solo. Storia completamente diversa sul desktop, in cui lo stesso codice genererà un'eccezione. Vedere stackoverflow.com/questions/4665179/...
someUIView.Subviews.All( v => { v.RemoveFromSuperview(); return true; } );
. IMHO più pulito per dire quello che vuoi dire: someUIView.Subviews.ToList().ForEach( v => v.RemoveFromSuperview() );
.
Ricevi tutte le visualizzazioni secondarie dal tuo controller di root e invia a ognuna una rimozione
NSArray *viewsToRemove = [self.view subviews];
for (UIView *v in viewsToRemove) {
[v removeFromSuperview];
}
self.view
come hai fatto tu.
for (UIView *v in [self.view subviews])
è più facile
In Swift puoi utilizzare un approccio funzionale come questo:
view.subviews.forEach { $0.removeFromSuperview() }
A titolo di confronto, l' approccio imperativo sarebbe simile al seguente:
for subview in view.subviews {
subview.removeFromSuperview()
}
Questi frammenti di codice funzionano solo su iOS / tvOS , tuttavia le cose sono leggermente diverse su macOS.
(subviews as [UIView]).map { $0.removeFromSuperview() }
.map
. questo è un effetto collaterale puro ed è gestito meglio in questo modo:view.subviews.forEach() { $0.removeFromSuperview() }
Se vuoi rimuovere tutte le visualizzazioni secondarie sul tuo UIView (qui yourView
), quindi scrivi questo codice con il tuo pulsante fai clic:
[[yourView subviews] makeObjectsPerformSelector: @selector(removeFromSuperview)];
Questo vale solo per OSX poiché in iOS viene conservata una copia dell'array
Quando si rimuovono tutte le visualizzazioni secondarie, è una buona idea iniziare a eliminare alla fine dell'array e continuare a eliminare fino a raggiungere l'inizio. Questo può essere realizzato con queste due righe di codice:
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();
}
o (meno efficiente, ma più leggibile)
for subview in mySuperView.subviews.reverse() {
subview.removeFromSuperview()
}
NOTA
NON è necessario rimuovere le visualizzazioni secondarie nell'ordine normale, poiché potrebbe causare un arresto anomalo se un'istanza di UIView viene eliminata prima diremoveFromSuperview
messaggio sia stato inviato a tutti gli oggetti dell'array. (Ovviamente, l'eliminazione dell'ultimo elemento non causerebbe un arresto anomalo)
Pertanto, il codice
[[someUIView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
NON dovrebbe essere usato.
Citazione dalla documentazione Apple su makeObjectsPerformSelector :
Invia a ciascun oggetto dell'array il messaggio identificato da un determinato selettore, iniziando dal primo oggetto e proseguendo attraverso l'array fino all'ultimo oggetto.
(che sarebbe la direzione sbagliata per questo scopo)
removeFromSuperview
termine, l'UIView verrà rimosso dall'array e, se non vi sono altre istanze viventi con una forte relazione con l'UIView, anche l'UIView verrà eliminato. Ciò può causare un'eccezione fuori limite.
[yourView subviews]
restituisce una COPIA dell'array, quindi è sicuro. (NOTA che su OSX, ciò che dici è corretto.)
Prova in questo modo swift 2.0
view.subviews.forEach { $0.removeFromSuperview() }
forEach
soluzione di base è stata aggiunta dopo la tua, l'ho persa. Scuse.
Utilizzare il codice seguente per rimuovere tutte le visualizzazioni secondarie.
for (UIView *view in [self.view subviews])
{
[view removeFromSuperview];
}
Per rimuovere la sintassi di tutte le visualizzazioni secondarie:
- (void)makeObjectsPerformSelector:(SEL)aSelector;
Utilizzo:
[self.View.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
Questo metodo è presente nel file NSArray.h e utilizza l'interfaccia NSArray (NSExtendedArray)
Se stai usando Swift, è semplice come:
subviews.map { $0.removeFromSuperview }
È simile in filosofia makeObjectsPerformSelector
all'approccio, tuttavia con un po 'più di sicurezza del tipo.
map
non dovrebbe provocare effetti collaterali. Inoltre, lo stesso risultato può essere raggiunto tramite forEach
.
Per iOS6 utilizzando il layout automatico ho dovuto aggiungere un po 'di codice per rimuovere anche i vincoli.
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)];
Sono sicuro che esiste un modo più ordinato per farlo, ma ha funzionato per me. Nel mio caso non ho potuto usare un direct in [tagview removeConstraints:tagview.constraints]
quanto c'erano vincoli impostati in XCode che venivano eliminati.
In monotouch / xamarin.ios questo ha funzionato per me:
SomeParentUiView.Subviews.All(x => x.RemoveFromSuperview);
Per rimuovere tutte le sottoview dalle superview:
NSArray *oSubView = [self subviews];
for(int iCount = 0; iCount < [oSubView count]; iCount++)
{
id object = [oSubView objectAtIndex:iCount];
[object removeFromSuperview];
iCount--;
}
iCount++
e iCount--
, lasciando l'indice lo stesso, quindi sarà un ciclo infinito se [oSubView count]>0
. Questo è sicuramente un codice errato e NON UTILIZZABILE .