显示在 MBProgressHUD 顶部的 UITableView 标题

Posted

技术标签:

【中文标题】显示在 MBProgressHUD 顶部的 UITableView 标题【英文标题】:UITableView headings shown on top of MBProgressHUD 【发布时间】:2011-08-26 03:22:59 【问题描述】:

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

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

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

    [HUD show:YES];

这是结果:

.

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

谢谢!

【问题讨论】:

请检查这个答案:***.com/a/28293970/3045072。希望对您有所帮助。 【参考方案1】:

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

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

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

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

【讨论】:

不错的解决方案,不幸的是由于ios 7中导航控件与状态栏的合并,状态栏也被覆盖层覆盖了。 这适用于我的用例。它还有一个额外的好处,那就是在底层表格视图控制器通过动画弹出堆栈时保持“正在保存..”对话框可见。 很遗憾,我的应用没有导航控制器,真的没有办法用ios找到超级视图吗?【参考方案2】:

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

【讨论】:

“直接将HUD添加到窗口”是什么意思? [self.view.window addSubview:HUD]; 似乎不起作用。我尝试更改为 UIViewController,它可以很好地显示 HUD,但由于某种原因,我的 UITableView 的所有元素都显示在一个相当大的表格的底部。当我将它改回 UITableViewController 时,内容再次正确显示。 “似乎不起作用”以什么方式?我认为它应该工作得很好。而且我不确定您在 UIViewController 上做错了什么,但请确保您的自动调整大小掩码设置正确。 我最终只是删除了视图并在 Interface Builder 中重新制作了它,并且由于某种原因这次它起作用了(作为 UIViewController)。谢谢大佬! 可能 self.view.window 在 vi​​ewWillAppear 之前被调用 - 在那之前它是 nil。 感谢@jtbandes,您的解决方案,即在 self.view.window 中添加 HUD 对我来说效果很好,但我仍然有一个问题,当我的应用程序加载第一个视图控制器时,即 rootViewController 然后它崩溃了。我不知道为什么会这样,谁能告诉我可能是什么问题?似乎 TomSwift 是对的,即 self.view.window 为 nil 但找不到解决方案。请帮忙【参考方案3】:

我的解决方案是:

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

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

【讨论】:

【参考方案4】:

在 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

【讨论】:

当你需要的子视图传入方法时,为什么要遍历每个子视图? 因为 tableview 的工作方式和 MBProgressHUD 您在将任何单元格添加到 TableView 之前添加 MBProgressView 的方式,如果您确实删除了 for 循环,您将不会始终将 MBProgressHUD 放在前面。跨度> 【参考方案5】:

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

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

【讨论】:

【参考方案6】:

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

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

@synthesize tableView;

添加以下代码到您的UITableViewController 子类的init 方法的开头,例如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.tableViewself.view 分开(这是对与self.tableView 相同的对象的引用,但现在是一个UIView,其中包含可能预期的表格视图)。

【讨论】:

【参考方案7】:

我刚刚手动解决了这个问题,距离 Chris Ballinger 询问已经 2 年了,但也许有人已经习惯了这里发生的事情。

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

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

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

【讨论】:

【参考方案8】:

我遇到了同样的问题,并决定通过将我的 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。

【讨论】:

【参考方案9】:

在.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];

【讨论】:

【参考方案10】:

这应该可以。

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

要删除你可以试试

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

【讨论】:

以上是关于显示在 MBProgressHUD 顶部的 UITableView 标题的主要内容,如果未能解决你的问题,请参考以下文章

为啥在HUD显示之前显示警报时不显示MBProgressHUD?

在 Core Data 存储迁移到新版本时,在 iPhone 应用程序的初始屏幕上显示 MBProgressHUD?

如何拦截 StoreKit“购买对话框”以使 MBProgressHUD / UIProgressView 在正确的时间正确显示?

MBProgressHUD 显示后,为何不能点击屏幕其他地方

滚动视图和 MBProgressHUD

如何快速使用 MBProgressHUD