iOS viewDidAppear вызывается до появления представления

Я работаю над приложением для iPhone / iPad с UISplitView. На левой панели у меня есть таблица, и все ячейки имеют переходы «Показать детали» к контроллерам навигации для правой панели.

Я выполняю длительные вычисления для нового представления после того, как пользователь выбирает параметр в таблице, поэтому у меня есть UIActivityIndicatorView, который я начинаю анимировать в «viewWillAppear». В viewDidAppear я выполняю вычисление, а затем обновляю соответствующие элементы пользовательского интерфейса и останавливаю UIActivityIndicatorView.

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

На iPad это выглядит так, как будто приложение зависает после нажатия на элемент в таблице. Затем данные появятся через несколько секунд. (Не помогает то, что мой тестовый iPad - это mini первого поколения, поэтому он медленнее.) Индикатора активности нет.

При отладке я обнаружил, что viewDidAppear на самом деле вызывается до появления представления. С дисплеем ничего не происходит, пока не вернется метод viewDidAppear. Я видел это с точкой останова, но я также подтвердил это без точек останова, поместив операторы NSLog в начало и конец viewDidAppear.

Так что это плохо выглядит; Интересно, могу ли я что-нибудь сделать с контроллером Segue, View Controller, Navigation Controller или Split View, чтобы заставить его вести себя так, как я хочу?

Заранее спасибо...


person Apollo Grace    schedule 07.03.2016    source источник


Ответы (2)


В конце концов я обошел это, добавив отложенное вычисление. Базовая ситуация, когда viewDidAppear появляется до появления представления, все еще раздражает, но этот обходной путь покрывает ее.

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    // Use delayed computation to get around "viewDidAppear" sometimes being called before view appears.
    [self.activityIndicator startAnimating];
    [self performSelector:@selector(delayedComputation) withObject:nil afterDelay:0.01f];
}

- (void)delayedComputation
{
    // (Perform lengthy calculations...)
    // (Refresh UI with results...)
    [self.activityIndicator stopAnimating];
}
person Apollo Grace    schedule 03.05.2016
comment
Столкнувшись с той же проблемой, я использовал showDetailViewController на UISplitViewController. Пока что задержка, как вы предположили, кажется единственным, что работает. Просто было интересно, есть ли другие решения. - person user1046037; 25.04.2018

Вы должны делать это асинхронно, это влияет на вашу производительность, потому что процессы, которые вы выполняете для рендеринга данных, довольно большие и длительные, вам нужно делать все это в

    //Show you spinner here
    dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
        //Background Thread, your logic for get data
        dispatch_async(dispatch_get_main_queue(), ^(void){
            //Run UI Updates and hide spinner`enter code here`

        });
    });

и, вероятно, он будет вести себя так, как вы хотите.

person jose920405    schedule 07.03.2016