2009-10-04 9 views
34

Ho un UIView genitore con un numero di subviews. Periodicamente ho bisogno di rimuovere una sottoview e rimuoverlo completamente dal sistema. Qual è il modo corretto per farlo? Ho provato questo:Qual è il modo corretto per rimuovere una sottoview da una gerarchia della vista e aggiungerla a nuke?

UIView *v = [self.containerView viewWithTag:[n integerValue]]; 

[v removeFromSuperview]; 

e ottenuto un risultato bizzarro. Anche i precedenti UIView sono scomparsi. Cosa sta succedendo?

risposta

66

Prova questo:

UIView *v = [self.containerView viewWithTag:[n integerValue]]; 
v.hidden = YES; 
[self.containerView bringSubviewToFront:v]; 
[v removeFromSuperview]; 

Un'altra cosa che ho appena notato dal documento di classe UIView - vedi l'ultima frase:

removeFromSuperview scollega il ricevitore dalla sua superview e la sua finestra, e lo rimuove dalla la catena di risposta.

  • (void) removeFromSuperview

Discussione Se superview del ricevitore non è pari a zero, questo metodo rilascia il ricevitore. Se si prevede di riutilizzare la vista, assicurarsi di conservarla prima di chiamare questo metodo e assicurarsi di rilasciarla come appropriato al termine dell'operazione o dopo averla aggiunta a un'altra gerarchia di viste.

Non invocare mai questo metodo durante la visualizzazione.

AGGIORNAMENTO: Ora è 2014 e rimuovere una sottoview senza nasconderlo funziona perfettamente bene. Il codice del manifesto originale dovrebbe funzionare così com'è:

UIView *v = [self.containerView viewWithTag:[n integerValue]]; 
[v removeFromSuperview]; 

Questo eliminerà v ed eventuali pareri si è collegato ad esso come subviews, lasciando dietro di sé containerView ed eventuali fratelli di v.

+1

** minaccioso ** Non invocare questo metodo durante la visualizzazione. – Irwin

+0

non potrebbe essere più facile, fallo come dice Blackberry per (UIView * s in [visualizza sottoview]) [s removeFromSuperview]; ** – Fattie

+0

Indietro nel '09, se hai rimosso una sottoview prima di nasconderla, hai alcuni risultati strani. O almeno questo è quello che stavo vedendo, così come il poster originale. E c'era un avvertimento nel riferimento alla classe UIView, che è stato sostituito con un altro. Direi che il metodo del poster originale di rimuovere una sottoview è probabilmente corretto e non richiede alcun codice aggiuntivo. (sta solo rimuovendo una sottoview singola) – mahboudz

0

Questa è la giusta idea generale. quelle altre UIViews che spariscono, qual è il loro rapporto con questo UIView? Sono sottoview di questa vista? Sono dealloc'd nel metodo dealloc della vista che stai rimuovendo?

Sei sicuro che i tuoi Tag siano unici?

Sujal

+0

Tutti i fratelli alla vista che sto cercando di rimuovere scompaiono all'istante dallo schermo. Cosa? – dugla

+0

Tutti i fratelli hanno tag univoci, che è il modo in cui mi riferisco alle viste. – dugla

0

Sono solo scomparendo dal display, o scomparire dal display e la gerarchia vista? Cosa ti mostra il debugger?

0

È possibile che cell.contentView abbia lo stesso tag della vista secondaria che si desidera rimuovere? secondo il documentation viewWithTag rimuove:

La vista nella gerarchia del ricevente che corrisponde tag. Il ricevitore è incluso nella ricerca.

Se questo è il caso, è possibile che si rimuova inavvertitamente cell.contentView dalla cella. Se n è zero e la vista content della cella non ha alcun tag impostato, verrà impostata su 0 e causerà che ciò accada.

38

Per rimuovere tutte le subviews dalla visualizzazione:

for(UIView *subview in [view subviews]) { 
    [subview removeFromSuperview]; 
} 

Se si desidera rimuovere un po 'di vista specifica solo allora:

for(UIView *subview in [view subviews]) { 
    if([subview isKindOfClass:[UIButton class]]) { 
    [subview removeFromSuperview]; 
} else { 
    // Do nothing - not a UIButton or subclass instance 
} 
} 

È possibile anche eliminare viste sotto per valore tag:

for(UIView *subview in [view subviews]) { 
    if(subview.tag==/*your subview tag value here*/) { 
     [subview removeFromSuperview]; 

    } else { 
     // Do nothing - not a UIButton or subclass instance 
    } 
} 
+3

Mi piace meglio della risposta accettata. Sembra un approccio molto più diretto - e tu eri abbastanza completo includendo opzioni per scegliere qualsiasi cosa qualcuno volesse cancellare. +1. – GeneralMike

+0

hmm ... in realtà ora che ho provato a farlo, non funziona. Sto usando l'opzione isKindOfClass. Ho UILabels e UISliders nella mia UIView e sto cercando di eliminare tutti gli slider, quindi ho: 'if ([subview isKindOfClass: [UISlider class]]);' e restituisce true per tutto, comprese le etichette, quindi tutto viene cancellato. Ho provato a sostituire isKindOfClass con isMemberOfClass, e anche questo non funziona. C'è qualcosa di speciale in UISliders che renderebbe tutto questo non funzionante? – GeneralMike

+0

Capito il mio problema, ho avuto un errore di battitura che mi ha portato per sempre a trovarlo. Il codice funziona esattamente come mostrato qui. – GeneralMike

1

Swift 3.0:

let viewToRemove = mySuperView.viewWithTag(myTag) 
viewToRemove?.removeFromSuperview() 
Problemi correlati