svprogresshud objective ios objective-c iphone uitableview mbprogresshud

ios - svprogresshud objective c



Se muestran UITableView en la parte superior de MBProgressHUD (10)

Acabo de resolver ese problema de forma manual, pasaron dos años desde que Chris Ballinger me preguntó, pero tal vez alguien se acostumbre a lo que está sucediendo aquí.

En UITableViewController ejecuto un método HTTP en viewDidLoad, que se ejecuta en segundo plano para que la vista de tabla se cargue mientras se muestra el progreso que causa esa falla.

Añadí una bandera falsa que se cambia a yes en viewDidLoad, y en viewDidAppear algo así puede resolver ese problema.

-(void) viewDidAppear:(BOOL)animated{ if (flag) { [self requestSomeData]; } flag = YES; [super viewDidAppear:animated]; }

Así que tengo una subclase de UITableViewController que carga algunos datos de internet y usa MBProgressHUD durante el proceso de carga. Uso la inicialización estándar de MBProgressHUD.

HUD = [[MBProgressHUD alloc] initWithView:self.view]; [self.view addSubview:HUD]; HUD.delegate = self; HUD.labelText = @"Loading"; [HUD show:YES];

Este es el resultado:

.

¿Hay alguna manera de resolver este problema, o debería abandonar MBProgressHUD?

¡Gracias!


Cree una categoría en UITableView que tome su MBProgressHUD y lo ponga al frente, al hacerlo siempre aparecerá "arriba" y permitirá que el usuario use otros controles en su aplicación como un botón de retroceso si la acción lleva demasiado tiempo ( por ejemplo)

#import "UITableView+MBProgressView.h" @implementation UITableView (MBProgressView) - (void)didAddSubview:(UIView *)subview{ for (UIView *view in self.subviews){ if([view isKindOfClass:[MBProgressHUD class]]){ [self bringSubviewToFront:view]; break; } } } @end


Esto debería funcionar.

[MBProgressHUD showHUDAddedTo:self.navigationController.view animated:YES];

Y para eliminar puedes intentar

[MBProgressHUD hideHUDForView:self.navigationController.view animated:YES];


Hace unos minutos, entré en un problema similar y pude resolverlo después de que me indicaron la dirección correcta de una manera diferente (y en mi humilde opinión más elegante):

Agregue la siguiente línea al comienzo de su implementación de la subclase UITableViewController :

@synthesize tableView;

Agregue el siguiente código al principio de su método init de su subclase UITableViewController , como initWithNibName:bundle: (el comienzo de viewDidLoad podría funcionar también, aunque recomiendo un método init ):

if (!tableView && [self.view isKindOfClass:[UITableView class]]) { tableView = (UITableView *)self.view; } self.view = [[UIView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame]; self.tableView.frame = self.view.bounds; self.tableView.contentInset = UIEdgeInsetsMake(0.0, 0.0, 0.0, 0.0); [self.view addSubview:self.tableView];

Entonces ya no necesita cambiar el código que publicó en su pregunta. Lo que el código anterior hace es básicamente separar el self.tableView de self.view (que era una referencia al mismo objeto que self.tableView antes, pero ahora es un UIView contiene la vista de tabla como uno podría esperar).


Mi solución fue bastante simple. En lugar de usar la vista del yo, utilicé la vista del control de navegación del yo.

HUD = [[MBProgressHUD alloc] initWithView:self.navigationController.view]; [self.navigationController.view addSubview:HUD];

Esto debería funcionar para el OP porque su imagen muestra que está usando un UINavigationController . Si no tiene un UINavigationController , puede agregar otra vista sobre su UITableView y agregar el HUD a eso. Deberá escribir un pequeño código adicional para ocultar / mostrar esta vista adicional.

Una cosa desafortunada con esta solución simple (sin contar mi idea de agregar otra vista mencionada anteriormente) significa que el usuario no puede usar los controles de navegación mientras se muestra el HUD. Para mi aplicación, no es un problema. Pero si tiene una operación de larga ejecución y el usuario puede querer presionar Cancelar, esta no será una buena solución.


Mi solución fue:

self.appDelegate = (kmAppDelegate *)[[UIApplication sharedApplication] delegate]; . . _progressHUD = [[MBProgressHUD alloc] initWithView:self.appDelegate.window]; . [self.appDelegate.window addSubview:_progressHUD];

Funciona como un encanto para todos los escenarios relacionados con UITableViewController. Espero que esto ayude a alguien más. Feliz programación :)


Probablemente sea porque self.view es una UITableView, que puede agregar / quitar dinámicamente subvistas, incluidos los encabezados, que podrían terminar en la parte superior del HUD después de agregarlo como una subvista. Debe agregar el HUD directamente a la ventana, o (por un poco más de trabajo pero quizás un mejor resultado) puede implementar una subclase UIViewController que tenga una vista simple que contenga tanto la vista de tabla como la vista de HUD. De esa forma, podrías colocar el HUD completamente sobre la vista de tabla.


Tuve el mismo problema y decidí resolver esto cambiando mi UITableViewController a un UIViewController simple que tiene una UITableView como una subvista (similar a lo que jtbandes propuso como un enfoque alternativo en su respuesta aceptada). La ventaja de esta solución es que la interfaz de usuario del controlador de navegación no está bloqueada, es decir, los usuarios simplemente pueden dejar el ViewController en caso de que no deseen esperar más para que finalice su operación puntual.

Debes hacer los siguientes cambios:

Archivo de cabecera:

@interface YourViewController : UIViewController <UITableViewDelegate, UITableViewDataSource> - (id)initWithStyle:(UITableViewStyle)style; @end

Archivo de implementación:

@interface YourViewController () @property (nonatomic, retain) UITableView *tableView; @property (nonatomic, retain) MBProgressHUD *hud; @end @implementation YourViewController #pragma mark - #pragma mark Initialization & Memory Management - (id)initWithStyle:(UITableViewStyle)style; { self = [super init]; if (self) { // create and configure the table view _tableView = [[UITableView alloc] initWithFrame:CGRectNull style:style]; _tableView.delegate = self; _tableView.dataSource = self; } return self; } - (void)dealloc { self.tableView = nil; self.hud = nil; [super dealloc]; } #pragma mark - #pragma mark View lifecycle - (void)loadView { CGRect frame = [self boundsFittingAvailableScreenSpace]; self.view = [[[UIView alloc] initWithFrame:frame] autorelease]; // add UI elements self.tableView.frame = self.view.bounds; [self.view addSubview:self.tableView]; } - (void)viewWillDisappear:(BOOL)animated { // optionally [self cancelWhateverYouWereWaitingFor]; [self.hud hide:animated]; }

El método -(CGRect)boundsFittingAvailableScreenSpace es parte de mi UIViewController+FittingBounds category . Puede encontrar su implementación aquí: https://gist.github.com/Tafkadasoh/5206130 .


Una solución simple sería dar al índice z de la vista de HUD un valor grande, asegurándose de que se coloca delante de todas las otras subvistas.

Consulte esta respuesta para obtener información sobre cómo editar el índice z de UIView: https://.com/a/4631895/1766720 .


En .h

#import "AppDelegate.h" @interface ViewController : UITableViewController { MBProgressHUD *progressHUD; ASAppDelegate *appDelegate; }

En m

[UIApplication sharedApplication].networkActivityIndicatorVisible = YES; appDelegate = (ASAppDelegate *) [UIApplication sharedApplication].delegate; progressHUD = [MBProgressHUD showHUDAddedTo:appDelegate.window animated:YES]; progressHUD.labelText = @"Syncing To Sever"; [appDelegate.window addSubview:progressHUD];