cómo eliminar subviews de scrollview?


Cómo elimino todas las subviews de mi scrollview...

Tengo un uiview y un botón encima de él en el scrollview algo como esto....

Aquí está mi código para agregar subview en la vista de desplazamiento

-(void)AddOneButton:(NSInteger)myButtonTag {
lastButtonNumber = lastButtonNumber + 1;

if ((lastButtonNumber == 1) || ((lastButtonNumber%2) == 1)) {
btnLeft = 8;}
else if ((lastButtonNumber == 2) || ((lastButtonNumber%2) == 0)) {
btnLeft = 162;
}
CGRect frame1 = CGRectMake(btnLeft, btnTop, 150, 150);
CGRect frame2 = CGRectMake(btnLeft, btnTop, 150, 150);
UIButton *Button = [UIButton buttonWithType:UIButtonTypeCustom];
Button.frame = frame1;
Button.tag = myButtonTag;
[Button addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];
[Button setBackgroundColor:[UIColor clearColor]];
[Button setBackgroundImage:[UIImage imageNamed:@"WaitScreen.png"] forState:UIControlStateHighlighted];

    GraphThumbViewControllerobj = [[GraphThumbViewController alloc] initWithPageNumber:[[GraphIdArray objectAtIndex:myButtonTag]intValue]];
    GraphThumbViewControllerobj.view.frame=frame2;
    GraphThumbViewControllerobj.lblCounter.text=[NSString stringWithFormat:@"%d of %d",myButtonTag+1,flashCardsId.count];
    GraphThumbViewControllerobj.lblQuestion.text=[flashCardText objectAtIndex:myButtonTag];
    [myScrollView addSubview:GraphThumbViewControllerobj.view];


[myScrollView addSubview:Button];


if ((lastButtonNumber == 2) || ((lastButtonNumber%2) == 0)) {
btnTop = btnTop + 162;
}
if (btnTop+150 > myScrollView.frame.size.height) {
myScrollView.contentSize = CGSizeMake((myScrollView.frame.size.width), (btnTop+160));}
}

Y aquí está el código para eliminar subviews

if(myScrollView!=nil)
{
        while ([myScrollView.subviews count] > 0) {
            //NSLog(@"subviews Count=%d",[[myScrollView subviews]count]);
            [[[myScrollView subviews] objectAtIndex:0] removeFromSuperview];
}

Texto alternativo http://www.freeimagehosting.net/uploads/e5339a1f51.png

Author: teabot, 2009-08-21

8 answers

Para eliminar todas las subviews de cualquier vista, puede iterar sobre las subviews y enviar a cada una una llamada removeFromSuperview:

// With some valid UIView *view:
for(UIView *subview in [view subviews]) {
    [subview removeFromSuperview];
}

Esto es totalmente incondicional, sin embargo, y deshacerse de los subvistas en la vista. Si desea algo más fino, puede tomar cualquiera de varios enfoques diferentes:

  • Mantenga sus propias matrices de vistas de diferentes tipos para que pueda enviarlas removeFromSuperview mensajes más tarde de la misma manera
  • Mantenga todos sus puntos de vista donde los crea y se aferra a los punteros a esas vistas, para que pueda enviarlos removeFromSuperview individualmente según sea necesario
  • Agregue una instrucción if al bucle anterior, verificando la igualdad de clase. Por ejemplo, para eliminar solo todos los UIButtons (o subclases personalizadas de UIButton) que existen en una vista, podría usar algo como:
// Again, valid UIView *view:
for(UIView *subview in [view subviews]) {
    if([subview isKindOfClass:[UIButton class]]) {
        [subview removeFromSuperview];
    } else {
        // Do nothing - not a UIButton or subclass instance
    }
}
 103
Author: Tim,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-08-21 09:15:36

Una vieja pregunta; pero como es el primer éxito en Google para esto, pensé que también haría una nota que también hay este método:

[[myScrollView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];

No puedes hacer la comprobación de isKindOfClass con esto, pero sigue siendo una buena solución para conocer.

Editar: Otro punto a tener en cuenta es que la barra de desplazamiento de una vista de desplazamiento se agrega como una subvista a esa vista de desplazamiento. Por lo tanto, si itera a través de todas las subviews de una vista de desplazamiento, se encontrará con ella. Si se elimina se añadirá de nuevo - pero es es importante saber esto si solo espera que sus propias subclases de UIView estén allí.

Enmienda para Swift 3:

myScrollView.subviews.forEach { $0.removeFromSuperview() }
 37
Author: Wex,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-08 10:58:22

Para añadir a lo que dijo Tim, me di cuenta de que está etiquetando sus puntos de vista. Si desea eliminar una vista con una etiqueta determinada, puede usar:

[[myScrollView viewWithTag:myButtonTag] removeFromSuperview];
 9
Author: Terry Blanchard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-07-30 23:31:21

No creo que debas usar la sugerencia de enumeración rápida.

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

¿No se supone que esto arroja una excepción si cambia la colección que se está iterando? http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocFastEnumeration.html#//apple_ref/doc/uid/TP30001163-CH18-SW3

Este ejemplo puede ser mejor.

NSArray *subviews = [[scroller subviews] copy];
for (UIView *subview in subviews) {
    [subview removeFromSuperview];
}
[subviews release];
 8
Author: Coderdad,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-04-02 17:47:21

El problema con UIScrollView y otras subclases de UIView es que contienen inicialmente algunas vistas (como la barra de desplazamiento vertical y horizontal para UIScrollView). Así que creé una categoría de UIView para eliminar las Subviews filtradas en la clase.

Por ejemplo:

[UIScrollView removeAllSubviewsOfClass:[FooView class],[BarView class],nil];

El código:

- (void)removeAllSubviewsOfClass:(Class)firstClass, ... NS_REQUIRES_NIL_TERMINATION;


- (void)removeAllSubviewsOfClass:(Class)firstClass, ...
{
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"FALSEPREDICATE"];

    va_list args;
    va_start(args, firstClass);

    for (Class class = firstClass; class != nil; class = va_arg(args, Class)) 
    {
        predicate = [NSCompoundPredicate orPredicateWithSubpredicates:[NSArray arrayWithObjects:predicate,[NSPredicate predicateWithFormat:@"self isKindOfClass:%@",class], nil]];
    }

    va_end(args);
    [[self.subviews filteredArrayUsingPredicate:predicate] makeObjectsPerformSelector:@selector(removeFromSuperview)];

}
 2
Author: Julien,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-02-22 11:04:03

Lo mejor y más fácil es usar

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

Esto de hecho causa un bloqueo, ya que la regla básica es que el array no debe modificarse mientras se enumera, para evitar que podamos usar

[[scrollView subviews] 
           makeObjectsPerformSelector:@selector(removeFromSuperview)];

Pero a veces crash sigue apareciendo porque makeObjectsPerformSelector: enumerará y realiza selector, También en iOS 7 las operaciones de interfaz de usuario están optimizadas para realizar más rápido que en iOS 6, por lo tanto, la mejor manera de iterar matriz inversa y eliminar

NSArray *vs=[scrollView subviews];
for(int i=vs.count-1;i>=0;i--)
{
    [((UIView*)[vs objectAtIndex:i]) removeFromSuperview];
}

Nota: enumerar los daños modificación pero no iteración...

 1
Author: RamaKrishna Chunduri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-10-24 10:55:08

La manera más fácil y mejor es

 for(UIView *subview in [scrollView subviews]) {

     [subview removeFromSuperview];

 }
 0
Author: Shashank Kulshrestha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-01-16 07:01:06
for(subview) in self.scrollView.subviews {
        subview.removeFromSuperview()
}
 0
Author: johndpope,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-09 00:59:03