28

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

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

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

    [HUD show:YES];

这是结果:

结果.

有什么办法可以解决这个问题,还是我应该放弃 MBProgressHUD?

谢谢!

4

10 回答 10

41

我的解决方案非常简单。我没有使用 self 的视图,而是使用了 self 的 navigationController 的视图。

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

这应该适用于 OP,因为他的照片显示他正在使用UINavigationController. 如果您没有UINavigationController,您可以在 UITableView 顶部添加另一个视图,并将 HUD 添加到其中。您必须编写一些额外的代码来隐藏/显示这个额外的视图。

不幸的是,这个简单的解决方案(不包括我添加上面提到的另一个视图的想法)意味着用户在显示 HUD 时无法使用导航控件。对于我的应用程序,这不是问题。但是,如果您有一个长时间运行的操作并且用户可能想要按取消,这将不是一个好的解决方案。

于 2012-01-06T08:01:18.207 回答
15

这可能是因为它self.view是一个 UITableView,它可以动态添加/删除包括标题在内的子视图,在您将其添加为子视图后,这些子视图可能最终位于 HUD 之上。您应该将 HUD 直接添加到窗口中,或者(需要做更多的工作,但可能会获得更好的结果)您可以实现一个 UIViewController 子类,该子类具有一个包含表格视图和 HUD 视图的普通视图。这样您就可以将 HUD 完全放在表格视图的顶部。

于 2011-08-26T03:25:34.540 回答
3

我的解决方案是:

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

在涉及 UITableViewController 的所有场景中都像魅力一样工作。我希望这对其他人有帮助。快乐编程:)

于 2012-05-16T14:53:38.383 回答
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
于 2013-06-15T18:30:59.687 回答
2

一个简单的解决方法是为 HUD 视图的 z-index 设置一个较大的值,确保它位于所有其他子视图的前面。

查看此答案以获取有关如何编辑 UIView 的 z-index 的信息:https ://stackoverflow.com/a/4631895/1766720 。

于 2014-08-20T22:16:46.750 回答
1

几分钟前我遇到了一个类似的问题,并且在以不同的(恕我直言更优雅)的方式指出正确的方向后能够解决它:

在子类实现的开头 添加以下行:UITableViewController

@synthesize tableView;

将以下代码添加到子类init方法的开头UITableViewController,例如initWithNibName:bundle:viewDidLoad虽然我推荐一种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.tableViewfrom self.view(它是对与以前相同的对象的引用self.tableView,但现在是一个UIView包含 table view 的,正如人们所期望的那样)。

于 2013-03-07T14:18:33.817 回答
1

我刚刚手动解决了这个问题,克里斯·巴林格问已经 2 年了,但也许有人习惯了这里发生的事情。

在 UITableViewController 中,我在 viewDidLoad 中执行 HTTP 方法,该方法在后台运行,因此在显示进度时会加载表视图,从而导致该未命中。

我添加了一个错误标志,在 viewDidLoad 中更改为 yes,在 viewDidAppear 中类似的东西可以解决这个问题。

-(void) viewDidAppear:(BOOL)animated{
    if (flag) {
        [self requestSomeData];
    }
    flag = YES;
    [super viewDidAppear:animated];
}
于 2014-03-31T13:43:31.290 回答
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 。

于 2013-03-20T17:50:38.793 回答
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];
于 2014-08-09T04:12:45.953 回答
0

这应该有效。

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

要删除,您可以尝试

  [MBProgressHUD hideHUDForView:self.navigationController.view animated:YES];
于 2017-02-01T09:08:59.747 回答