ios - puedo - ¿Eliminar todas las subvistas?
itunes (15)
Al eliminar todas las subvistas, es una buena idea comenzar a eliminar al final de la matriz y seguir eliminando hasta que llegue al principio. Esto se puede lograr con estas dos líneas de código:
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 (menos eficiente, pero más legible)
for subview in mySuperView.subviews.reverse() {
subview.removeFromSuperview()
}
NOTA
NO debe eliminar las subvistas en el orden normal, ya que puede causar un bloqueo si se elimina una instancia de UIView antes de que el mensaje removeFromSuperview
se haya enviado a todos los objetos de la matriz. (Obviamente, eliminar el último elemento no causaría un bloqueo)
Por lo tanto, el código
[[someUIView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
NO debe utilizarse.
Cita de la documentación de Apple sobre makeObjectsPerformSelector :
Envía a cada objeto de la matriz el mensaje identificado por un selector dado, comenzando con el primer objeto y continuando a través de la matriz hasta el último objeto.
(que sería la dirección equivocada para este propósito)
Cuando mi aplicación vuelva a su controlador de vista raíz, en el método viewDidAppear:
necesito eliminar todas las subvistas.
¿Cómo puedo hacer esto?
En Swift puedes usar un enfoque funcional como este:
view.subviews.forEach { $0.removeFromSuperview() }
A modo de comparación, el enfoque imperativo se vería así:
for subview in view.subviews {
subview.removeFromSuperview()
}
Estos fragmentos de código solo funcionan en iOS / tvOS , aunque las cosas son un poco diferentes en macOS.
En monotouch / xamarin.ios esto funcionó para mí:
SomeParentUiView.Subviews.All(x => x.RemoveFromSuperview);
En objetivo C, siga adelante y cree un método de categoría fuera de la clase UIView.
- (void)removeAllSubviews
{
for (UIView *subview in self.subviews)
[subview removeFromSuperview];
}
Obtenga todas las subvistas de su controlador raíz y envíe a cada una un removeFromSuperview:
NSArray *viewsToRemove = [self.view subviews];
for (UIView *v in viewsToRemove) {
[v removeFromSuperview];
}
Para eliminar todas las subvistas Sintaxis:
- (void)makeObjectsPerformSelector:(SEL)aSelector;
Uso:
[self.View.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
Este método está presente en el archivo NSArray.h y utiliza la interfaz NSArray (NSExtendedArray)
Para eliminar todas las subvistas de superviews:
NSArray *oSubView = [self subviews];
for(int iCount = 0; iCount < [oSubView count]; iCount++)
{
id object = [oSubView objectAtIndex:iCount];
[object removeFromSuperview];
iCount--;
}
Para ios6 usando autolayout tuve que agregar un poco de código para eliminar las restricciones también.
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)];
Estoy seguro de que hay una forma más ordenada de hacer esto, pero funcionó para mí. En mi caso, no pude usar un [tagview removeConstraints:tagview.constraints]
ya que había restricciones establecidas en XCode que se estaban eliminando.
Prueba de esta manera swift 2.0
view.subviews.forEach { $0.removeFromSuperview() }
Si desea eliminar todas las subvistas en su UIView (aquí yourView
), escriba este código con el botón:
[[yourView subviews] makeObjectsPerformSelector: @selector(removeFromSuperview)];
Si estás usando Swift, es tan simple como:
subviews.map { $0.removeFromSuperview }
En filosofía, es similar al enfoque makeObjectsPerformSelector
, pero con un poco más de seguridad de tipo.
Usando la extensión Swift UIView
:
extension UIView {
func removeAllSubviews() {
for subview in subviews {
subview.removeFromSuperview()
}
}
}
Utilice el siguiente código para eliminar todas las subvistas.
for (UIView *view in [self.view subviews])
{
[view removeFromSuperview];
}
Edit: Gracias a cocoafan : Esta situación se confunde con el hecho de que NSView
y UIView
manejan las cosas de manera diferente. Para NSView
(solo en el desarrollo de Mac de escritorio), simplemente puede usar lo siguiente:
[someNSView setSubviews:[NSArray array]];
Para UIView
(solo desarrollo de iOS), puede usar con seguridad makeObjectsPerformSelector:
porque la propiedad subviews
devolverá una copia de la matriz de subviews:
[[someUIView subviews]
makeObjectsPerformSelector:@selector(removeFromSuperview)];
Gracias a Tommy por señalar que makeObjectsPerformSelector:
parece modificar la matriz de subviews
mientras se está enumerando (lo que hace para NSView
, pero no para UIView
).
Por favor vea esta pregunta SO para más detalles.
Nota: el uso de cualquiera de estos dos métodos eliminará todas las vistas que contenga su vista principal y las publicará , si no se conservan en otro lugar. De la documentación de Apple en removeFromSuperview :
Si la supervisión del receptor no es nula, este método libera el receptor. Si planea reutilizar la vista, asegúrese de conservarla antes de llamar a este método y de liberarla según corresponda cuando haya terminado con ella o después de agregarla a otra jerarquía de vistas.
view.subviews.forEach { $0.removeFromSuperview() }