显示在 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 在 viewWillAppear 之前被调用 - 在那之前它是 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.tableView
与self.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 在正确的时间正确显示?