UITableView 标题显示在 MBProgressHUD 顶部

发布于 2024-12-01 15:25:36 字数 432 浏览 11 评论 0原文

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

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

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

    [HUD show:YES];

这是结果:

result

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

谢谢!

So I have a subclass of UITableViewController that loads some data from the internet and uses MBProgressHUD during the loading process. I use the standard MBProgressHUD initialization.

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

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

    [HUD show:YES];

This is the result:

result.

Is there any way to resolve this issue, or should I just abandon MBProgressHUD?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

将军与妓 2024-12-08 15:25:36

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

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

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

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

My solution was pretty simple. Instead of using self's view, I used self's navigationController's view.

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

This should work for the OP because his picture shows he's using a UINavigationController. If you don't have a UINavigationController, you might add another view on top of your UITableView, and add the HUD to that. You'll have to write a little extra code to hide/show this extra view.

An unfortunate thing with this simple solution (not counting my idea adding another view mentioned above) means the user can't use the navigation controls while the HUD is showing. For my app, it's not a problem. But if you have a long running operation and the user might want to press Cancel, this will not be a good solution.

渡你暖光 2024-12-08 15:25:36

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

It's probably because self.view is a UITableView, which may dynamically add/remove subviews including the headers, which could end up on top of the HUD after you add it as a subview. You should either add the HUD directly to the window, or (for a little more work but perhaps a better result) you could implement a UIViewController subclass which has a plain view containing both the table view and the HUD view. That way you could put the HUD completely on top of the table view.

草莓酥 2024-12-08 15:25:36

我的解决方案是:

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

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

My solution was:

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

Works like a charm for all scenarios involving the UITableViewController. I hope this helps someone else. Happy Programming :)

神魇的王 2024-12-08 15:25:36

在 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

Create a category on UITableView that will take your MBProgressHUD and bring it to the front, by doing so it will always appear "on top" and let the user use other controls in your app like a back button if the action is taking to long (for example)

#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
混浊又暗下来 2024-12-08 15:25:36

一个简单的修复方法是为 HUD 视图的 z-index 赋予一个较大的值,确保其放置在所有其他子视图的前面。

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

A simple fix would be to give the z-index of the HUD view a large value, ensuring it is placed in front of all the other subviews.

Check out this answer for information on how to edit a UIView's z-index: https://stackoverflow.com/a/4631895/1766720.

场罚期间 2024-12-08 15:25:36

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

添加以下行 < 开始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.tableViewself.view 分开(这是对与 self.tableView 相同对象的引用)之前,但现在是一个包含表格视图的 UIView,正如人们所期望的那样)。

I've stepped into a similar problem a few minutes ago and was able to solve it after being pointed to the right direction in a different (and IMHO more elegant) way:

Add the following line at the beginning of your UITableViewController subclass implementation:

@synthesize tableView;

Add the following code to the beginning of your init method of your UITableViewController subclass, like initWithNibName:bundle: (the beginning of viewDidLoad might work as well, although I recommend an init method):

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

Then you don't need to change your code you posted in your question any more. What the above code does is basically seperating the self.tableView from self.view (which was a reference to the same object as self.tableView before, but now is a UIView containing the table view as one might expect).

⊕婉儿 2024-12-08 15:25:36

我刚刚手动解决了这个问题,克里斯·巴林格 (Chris Ballinger) 提问已经过去两年了,但也许有人已经习惯了这里发生的事情。

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

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

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

I've Just solved that issue manually , it has been 2 years since Chris Ballinger asked but maybe someone get used of what is going on here.

In UITableViewController i execute an HTTP method in viewDidLoad , which is running in background so the table view is loaded while the progress is shown causing that miss.

i added a false flag which is changed to yes in viewDidLoad, And in viewDidAppear something like that can solve that problem.

-(void) viewDidAppear:(BOOL)animated{
    if (flag) {
        [self requestSomeData];
    }
    flag = YES;
    [super viewDidAppear:animated];
}
请帮我爱他 2024-12-08 15:25:36

我遇到了同样的问题,并决定通过将 UITableViewController 更改为普通 UIViewController 来解决此问题,该 UITableView 作为子视图(类似于 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 类别。您可以在这里找到它的实现:https://gist.github.com/Tafkadasoh/5206130

I had the same problem and decided to solve this by changing my UITableViewController to a plain UIViewController that has a UITableView as a subview (similar to what jtbandes proposed as an alternative approach in his accepted answer). The advantage of this solution is that the UI of the navigation controller isn't blocked, i.e. users can simply leave the ViewController in case they don't want to waiting any longer for your timely operation to finish.

You need to do the following changes:

Header file:

@interface YourViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
- (id)initWithStyle:(UITableViewStyle)style;
@end

Implementation file:

@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];
}

The method -(CGRect)boundsFittingAvailableScreenSpace is part of my UIViewController+FittingBounds category. You can find its implementation here: https://gist.github.com/Tafkadasoh/5206130.

输什么也不输骨气 2024-12-08 15:25:36

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

In .h

#import "AppDelegate.h"

@interface ViewController : UITableViewController
{
    MBProgressHUD *progressHUD;
    ASAppDelegate *appDelegate;
}

In .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];
再可℃爱ぅ一点好了 2024-12-08 15:25:36

这应该有效。

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

要删除你可以尝试

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

This should work.

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

And to remove you can try

  [MBProgressHUD hideHUDForView:self.navigationController.view animated:YES];
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文