MBProgressHUD顶部显示的UITableView标题

时间:2011-08-26 03:23:00

标签: ios objective-c iphone uitableview mbprogresshud

所以我有一个UITableViewController的子类,它从加载一些数据并在加载过程中使用MBProgressHUD。我使用标准的MBProgressHUD初始化。

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

    HUD.delegate = self;
    HUD.labelText = @"Loading";

    [HUD show:YES];

结果如下:

result

有没有办法解决这个问题,还是我应该放弃MBProgressHUD?

谢谢!

10 个答案:

答案 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];