Заголовки UITableView показаны поверх MBProgressHUD - PullRequest
28 голосов
/ 26 августа 2011

Итак, у меня есть подкласс 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 ]

41 голосов
/ 06 января 2012

Мое решение было довольно простым. Вместо того, чтобы использовать вид self, я использовал вид self navigationController.

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

Это должно работать для ОП, потому что на его рисунке видно, что он использует UINavigationController. Если у вас нет UINavigationController, вы можете добавить другое представление поверх вашего UITableView и добавить к нему HUD. Вам нужно будет написать немного дополнительного кода, чтобы скрыть / показать этот дополнительный вид.

Неудачная вещь с этим простым решением (не считая моей идеи добавления другого вида, упомянутого выше) означает, что пользователь не может использовать элементы управления навигацией, когда HUD показывает. Для моего приложения это не проблема. Но если у вас длительная операция и пользователь может захотеть нажать Отмена, это не будет хорошим решением.

15 голосов
/ 26 августа 2011

Вероятно, это связано с тем, что self.view - это UITableView, который может динамически добавлять / удалять подпредставления, включая заголовки, которые могут оказаться в верхней части HUD после добавления его в качестве подпредставления. Вы должны либо добавить HUD непосредственно в окно, либо (для небольшой работы, но, возможно, для лучшего результата) вы можете реализовать подкласс UIViewController, который имеет простое представление, содержащее как представление таблицы, так и представление HUD. Таким образом, вы можете поместить HUD полностью поверх таблицы.

3 голосов
/ 16 мая 2012

Мое решение было:

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

Работает как очарование для всех сценариев, включающих UITableViewController. Я надеюсь, что это помогает кому-то еще. Удачного программирования:)

2 голосов
/ 21 августа 2014

Простым решением было бы придать z-индексу вида HUD большое значение, обеспечив его размещение перед всеми остальными подпредставлениями.

Проверьте этот ответ для получения информации о том, как редактировать z-индекс UIView: https://stackoverflow.com/a/4631895/1766720.

2 голосов
/ 15 июня 2013

Создайте категорию на 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
1 голос
/ 31 марта 2014

Я только что решил эту проблему вручную, прошло 2 года с тех пор, как спросил Крис Баллинджер, но, возможно, кто-то привык к тому, что здесь происходит.

В UITableViewController я выполняю HTTP-метод в viewDidLoad, который работает в фоновом режиме, поэтому табличное представление загружается, пока отображается прогресс, вызывающий эту ошибку.

я добавил ложный флаг, который был изменен на да в viewDidLoad, а во viewDidAppear что-то подобное может решить эту проблему.

-(void) viewDidAppear:(BOOL)animated{
    if (flag) {
        [self requestSomeData];
    }
    flag = YES;
    [super viewDidAppear:animated];
}
1 голос
/ 07 марта 2013

Я столкнулся с подобной проблемой несколько минут назад и смог ее решить, указав правильное направление другим (и ИМХО более элегантным) способом:

Добавьте следующую строку в начале вашего подкласса 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.tableView от self.view (который был ссылкой на тот же объект, что и self.tableView ранее, но теперь это UIView, содержащий табличное представление, как и следовало ожидать).

0 голосов
/ 01 февраля 2017

Это должно работать.

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

А для удаления можно попробовать

  [MBProgressHUD hideHUDForView:self.navigationController.view animated:YES];
0 голосов
/ 09 августа 2014

In .h

#import "AppDelegate.h"

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

дюйм.

[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];
0 голосов
/ 20 марта 2013

У меня была та же проблема, и я решил ее решить, заменив мой UITableViewController на простой UIViewController с UITableView в качестве подпредставления (аналогично тому, что jtbandes предложил в качестве альтернативного подхода в своем принятом ответе).Преимущество этого решения заключается в том, что пользовательский интерфейс контроллера навигации не блокируется, то есть пользователи могут просто покинуть 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.

...