ios uitableview uiactivityindicatorview

IOS: ActivityIndicator over UITableView... ¿Cómo?



uiactivityindicatorview (5)

Quiero mostrar un indicador de actividad sobre una vista adecuada mientras se cargan datos (en otro hilo). Entonces, en el método ViewDidLoad del UITableViewController:

-(void)viewDidLoad { [super viewDidLoad]; //I create the activity indicator UIActivityIndicatorView *ac = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; [ac startAnimating]; //Create the queue to download data from internet dispatch_queue_t downloadQueue = dispatch_queue_create("PhotoDownload",NULL); dispatch_async(downloadQueue, ^{ //Download photo ....... ....... dispatch_async(dispatch_get_main_queue(), ^{ ...... ...... [ac stopAnimating]; }); }); .......

¿Por qué el indicador de actividad no se muestra en la vista de tabla? ¿Cómo puedo lograrlo?


Aunque la pregunta, es bastante antigua, añado también la mía. [IOS 8+] Lo anterior no funciona para mí. En su lugar, almaceno la vista del indicador (ac) en la clase. Entonces lo hago:

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { if (ac.isAnimating) return 50.0f; return 0.0f; } - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { if (ac.isAnimating) return ac; return nil; }

Por mostrar el indicador de vista que hago.

[ac startAnimating]

Por ocultarlo, lo hago.

[ac stopAnimating]

Espero que esto sea de ayuda para alguien.


Hay una solución para UIViewController. (Puede usar un UIViewController con una vista de tabla para lograr un UITableViewController). En el guión gráfico, agregue un ActivityIndicator en la vista de UIViewController. Luego, en viewDidLoad, agregue lo siguiente:

[self.activityIndicator layer].zPosition = 1;

El indicador de actividad se mostrará en la vista de tabla.


He estado tratando de encontrar una solución para eso y he leído muchos foros, pero no conseguí lo que quería. Después de comprender cómo funcionan el indicador de actividad y el controlador de vista de tabla, se me ocurrió la siguiente solución.

Por alguna razón, si intenta iniciar el indicador de actividad en el mismo subproceso con tableReload o cualquier otro proceso costoso, el indicador de actividad nunca se ejecuta. Si intenta ejecutar la recarga de la tabla o alguna otra operación en otro subproceso, es posible que no sea seguro y produzca errores o resultados no deseados. Así que podemos ejecutar el método que presenta el indicador de actividad en otro hilo.

También he combinado esta solución con MBProgressHUD para presentar algo que se vea mejor que una vista con un indicador de actividad. En cualquier caso, los looks de la activityView pueden ser personalizados.

-(void)showActivityViewer { AppDelegate *delegate = [[UIApplication sharedApplication] delegate]; UIWindow *window = delegate.window; activityView = [[UIView alloc] initWithFrame: CGRectMake(0, 0, window.bounds.size.width, window.bounds.size.height)]; activityView.backgroundColor = [UIColor blackColor]; activityView.alpha = 0.5; UIActivityIndicatorView *activityWheel = [[UIActivityIndicatorView alloc] initWithFrame: CGRectMake(window.bounds.size.width / 2 - 12, window.bounds.size.height / 2 - 12, 24, 24)]; activityWheel.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhite; activityWheel.autoresizingMask = (UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin); [activityView addSubview:activityWheel]; [window addSubview: activityView]; [[[activityView subviews] objectAtIndex:0] startAnimating]; } -(void)hideActivityViewer { [[[activityView subviews] objectAtIndex:0] stopAnimating]; [activityView removeFromSuperview]; activityView = nil; } - (IBAction)reloadDataAction:(id)sender { [NSThread detachNewThreadSelector:@selector(showActivityViewer) toTarget:self withObject:nil]; //... do your reload or expensive operations [self hideActivityViewer]; }


Necesitas agregar el UIActivityIndicatorView a algo. Puedes agregarlo a una vista de cabecera de UITableView. Para ello, deberá proporcionar su propia vista personalizada.

... UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 50)]; [view addSubview:ac]; // <-- Your UIActivityIndicatorView self.tableView.tableHeaderView = view; ...


[iOS 5 +]
Si solo desea mostrar la actividadWheel sin una vista de padre adicional, también puede agregar la actividadWheel directamente a la vista de tabla y calcular el valor de y para el marco utilizando el valor de tablaViews contentOffset:

@interface MyTableViewController () @property (nonatomic, strong) UIActivityIndicatorView *activityView; @end // .... - (void) showActivityView { if (self.activityView==nil) { self.activityView = [[UIActivityIndicatorView alloc] initWithFrame:CGRectZero]; [self.tableView addSubview:self.activityView]; self.activityView.activityIndicatorViewStyle = UIActivityIndicatorViewStyleWhiteLarge; self.activityView.hidesWhenStopped = YES; // additional setup... // self.activityView.color = [UIColor redColor]; } // Center CGFloat x = UIScreen.mainScreen.applicationFrame.size.width/2; CGFloat y = UIScreen.mainScreen.applicationFrame.size.height/2; // Offset. If tableView has been scrolled CGFloat yOffset = self.tableView.contentOffset.y; self.activityView.frame = CGRectMake(x, y + yOffset, 0, 0); self.activityView.hidden = NO; [self.activityView startAnimating]; } - (void) hideActivityView { [self.activityView stopAnimating]; }

Si el activityView no se muestra de inmediato (o nunca), consulte la respuesta de zirinisp o realice el trabajo pesado en segundo plano.