所以我有一个UITableViewController的子类,它从加载一些数据并在加载过程中使用MBProgressHUD。我使用标准的MBProgressHUD初始化。
HUD = [[MBProgressHUD alloc] initWithView:self.view];
[self.view addSubview:HUD];
HUD.delegate = self;
HUD.labelText = @"Loading";
[HUD show:YES];
结果如下:
有没有办法解决这个问题,还是我应该放弃MBProgressHUD?
谢谢!
答案 0 :(得分:41)
我的解决方案非常简单。我没有使用自己的视图,而是使用了self的navigationController视图。
HUD = [[MBProgressHUD alloc] initWithView:self.navigationController.view];
[self.navigationController.view addSubview:HUD];
这应该适用于OP,因为他的照片显示他正在使用UINavigationController
。如果您没有UINavigationController
,则可以在UITableView上添加另一个视图,并将HUD添加到该视图中。你必须写一些额外的代码来隐藏/显示这个额外的视图。
这个简单的解决方案(不包括上面提到的另一个视图我的想法)的一个不幸的事情意味着用户在HUD显示时无法使用导航控件。对于我的应用程序,这不是问题。但是如果你有一个长时间运行的操作并且用户可能想要按下取消,这将不是一个好的解决方案。
答案 1 :(得分:15)
这可能是因为self.view
是一个UITableView,它可以动态添加/删除包含标题的子视图,在将其添加为子视图后,最终可能会在HUD之上。你应该直接将HUD添加到窗口,或者(为了更多的工作,但可能是更好的结果),你可以实现一个UIViewController子类,它有一个包含表视图和HUD视图的普通视图。这样你就可以将HUD完全置于表格视图的顶部。
答案 2 :(得分:3)
我的解决方案是:
self.appDelegate = (kmAppDelegate *)[[UIApplication sharedApplication] delegate];
.
.
_progressHUD = [[MBProgressHUD alloc] initWithView:self.appDelegate.window];
.
[self.appDelegate.window addSubview:_progressHUD];
就像涉及UITableViewController的所有场景的魅力一样。我希望这有助于其他人。快乐编程:)
答案 3 :(得分:2)
在UITableView上创建一个类别,它将把你的MBProgressHUD带到前面,通过这样做,它总是显示在“顶部”,让用户在你的应用程序中使用其他控件,如果操作正在进行长(例如)
#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
答案 4 :(得分:2)
一个简单的解决方法是给HUD视图的z-index一个很大的值,确保它放在所有其他子视图的前面。
有关如何编辑UIView的z-index的信息,请查看此答案:https://stackoverflow.com/a/4631895/1766720。
答案 5 :(得分:1)
几分钟前我遇到了类似的问题,并且在以不同的方式指向正确的方向(并且恕我直言更优雅)之后能够解决它:
在 UITableViewController
子类实施的开头添加以下行:
@synthesize tableView;
将以下代码添加到init
子类的UITableViewController
方法的开头,例如initWithNibName:bundle:
(开头) viewDidLoad
的{{1}}可能也有效,但我建议使用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];
然后您不再需要更改您在问题中发布的代码。上面代码的作用基本上是从self.tableView
分隔self.view
(之前是对self.tableView
的同一个对象的引用,但现在是包含表视图的UIView
正如人们所预料的那样。)
答案 6 :(得分:1)
我刚刚手动解决了这个问题,自从Chris Ballinger提出要求已经有2年了,但是也许有人会对这里发生的事情有所了解。
在UITableViewController中,我在viewDidLoad中执行HTTP方法,该方法在后台运行,因此在显示进度时会加载表视图,从而导致错过。
我添加了一个假标志,在viewDidLoad中更改为yes,而在viewDidAppear中,类似的东西可以解决这个问题。
-(void) viewDidAppear:(BOOL)animated{
if (flag) {
[self requestSomeData];
}
flag = YES;
[super viewDidAppear:animated];
}
答案 7 :(得分:0)
我遇到了同样的问题并且决定通过将我的UITableViewController更改为具有UITableView作为子视图的普通UIViewController来解决这个问题(类似于 jtbandes 在他接受的答案中提出的替代方法) 。此解决方案的优点是导航控制器的UI未被阻止,即用户可以简单地离开ViewController,以防他们不想再等待您的及时操作完成。
您需要进行以下更改:
标题文件:
@interface YourViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
- (id)initWithStyle:(UITableViewStyle)style;
@end
实施文件:
@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];
}
方法-(CGRect)boundsFittingAvailableScreenSpace
是我UIViewController+FittingBounds category
的一部分。您可以在此处找到它的实现:https://gist.github.com/Tafkadasoh/5206130。
答案 8 :(得分:0)
在.h
#import "AppDelegate.h"
@interface ViewController : UITableViewController
{
MBProgressHUD *progressHUD;
ASAppDelegate *appDelegate;
}
在.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];
答案 9 :(得分:0)
这应该有效。
[MBProgressHUD showHUDAddedTo:self.navigationController.view animated:YES];
要删除,您可以尝试
[MBProgressHUD hideHUDForView:self.navigationController.view animated:YES];