Подтвердить что ты не робот

Заголовки UITableView, показанные поверх MBProgressHUD

Итак, у меня есть подкласс UITableViewController, который загружает некоторые данные из Интернета и использует MBProgressHUD во время процесса загрузки. Я использую стандартную инициализацию MBProgressHUD.

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

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

    [HUD show:YES];

Это результат:

result.

Есть ли способ решить эту проблему, или я должен просто отказаться от MBProgressHUD?

Спасибо!

4b9b3361

Ответ 1

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

Ответ 2

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

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

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

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

Ответ 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

Ответ 5

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

Ознакомьтесь с этим ответом для получения информации о том, как отредактировать z-index UIView: fooobar.com/questions/30822/....

Ответ 6

Несколько минут назад я столкнулся с подобной проблемой и смог ее решить, указав правильное направление в другом (и более элегантном):

Добавьте следующую строку в начале 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, содержащий табличный вид, как и следовало ожидать).

Ответ 7

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

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

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

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

Ответ 8

У меня была та же проблема, и я решил решить эту проблему, изменив свой 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.

Ответ 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];