objective-c iphone xcode uiscrollview

objective c - ¿Cómo eliminar las subvistas de scrollview?



scrollview swift (8)

¿Cómo elimino todas las subvistas de mi scrollview ...?

Tengo una uiview y un botón encima en la vista de desplazamiento algo así ...

aquí está mi código para agregar subvista 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 las subvistas

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


El problema con la subclase UIScrollView y otros 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 Subvistas 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)]; }


La manera más fácil y mejor es

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


Lo mejor y más fácil es usar

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

Esto causa un bloqueo ya que la regla básica es que la matriz no debe modificarse mientras se enumera, para evitar que podamos utilizarla

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

Pero a veces el colapso sigue apareciendo porque makeObjectsPerformSelector: enumerará y realizará el selector, también en iOS 7 las operaciones de ui están optimizadas para funcionar más rápido que en iOS 6, de ahí la mejor manera de iterar el conjunto de forma inversa y eliminar

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

Nota: la enumeración perjudica la modificación pero no itera ...


No creo que deba 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 cambias la colección que se itera? 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];


Para agregar a lo que Tim dijo, noté que estás etiquetando tus puntos de vista. Si quisiera eliminar una vista con cierta etiqueta, podría usar:

[[myScrollView viewWithTag:myButtonTag] removeFromSuperview];


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

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

Sin embargo, esto es completamente incondicional y eliminará todas las subvistas en la vista dada. Si quieres algo más refinado, puedes tomar diferentes enfoques:

  • Mantenga sus propias matrices de vistas de diferentes tipos para que pueda enviarles mensajes removeFromSuperview más tarde de la misma manera
  • Conserva todas las vistas en las que las removeFromSuperview y aferra punteros a esas vistas, para que puedas enviarlas removeFromSuperview individualmente según sea necesario
  • Agregue una instrucción if al ciclo anterior, verificando la igualdad de clases. 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 } }


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

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

No puede 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 repite todas las subvistas de una vista de desplazamiento, se encontrará con ella. Si se elimina, se volverá a agregar a sí mismo, pero es importante saber esto si solo espera que sus propias subclases UIView estén ahí.

Enmienda para Swift 3:

myScrollView.subviews.forEach { $0.removeFromSuperview() }


for(subview) in self.scrollView.subviews { subview.removeFromSuperview() }