Просмотр не обновляется, но все в главном потоке - PullRequest
2 голосов
/ 07 октября 2010

Я пытаюсь показать UIProgressView поверх табличного представления после определенных взаимодействий с пользователем. В моем табличном представлении, если пользователь нажимает на одну конкретную ячейку, я перемещаю UIView, который содержит панель инструментов с элементами панели и представление выбора (оно очень похоже на лист действий). Когда я делаю это, я добавляю вид за пределы экрана к текущему виду, а затем анимирую слайд. Когда пользователь делает выбор и нажимает «готово», вид снова выдвигается. В этот момент предполагается, что представление прогресса отображается и обновляется по мере того, как происходят некоторые события в фоновом режиме.

Проблема, с которой я столкнулся, заключается в том, что после того, как «лист предупреждений» UIView выскользнул из текущего представления, в пользовательском интерфейсе давно ничего не происходит. Когда я показываю скользящий вид, я делаю это:

[[[UIApplication sharedApploication] keyWindow] addSubview:slidingView];
CGRect newFrame = CGRectMake(...);
[UIView animateWithDuration:0.3
    animations:^{
        slidingView.frame = newFrame;
    }];

Когда пользователь нажимает кнопку «Готово» в режиме скольжения, вызывается этот метод действия:

- (void) done {
    NSNumber *row = GetSelectedRowSomehow();

    [self dismiss:@selector(doneCallback:) withObject:row];
}

- (void) dismiss:(SEL)cb withObject:(id)obj {
    [UIView animateWithDuration:0.3
        animations:^{
            slidingView.frame = CGRectMake(...);
        }
        completion:^(BOOL finished) {
            [self.delegate performSelectorOnMainThread:cb
                                            withObject:obj
                                         waitUntilDone:NO];
            [slidingView performSelectorOnMainThread:@selector(removeFromSuperview:)
                                          withObject:nil
                                       waitUntilDone:NO];
        }];
}

Обратный вызов, который вызывается здесь:

- (void) doneCallback {
    self.dialogView.hidden = NO;
    self.progressView.progress = 0;

    for (float i = 0; i < 1.0; i += 0.1) {
        self.progressView.progress += i;
        sleep(0.5);
    }
}

В моем случае dialogView не появляется до тех пор, пока не завершится callback. Почему бы просто не обновить дисплей сразу после того, как его свойство hidden было установлено на NO?

1 Ответ

2 голосов
/ 07 октября 2010

Дисплей обновляется в главном потоке, как только ваш код завершает выполнение, поэтому, блокируя основной поток, вы предотвращаете это.

Одна из причин этого заключается в том, что обновления объединены в пакеты, чтобы их можно было эффективно перерисовать.

Одним из решений / обходного пути было бы использование executeSelector: afterDelay: 0,01 до в doneCallback после hidden = NO, перемещая следующий код в новый селектор, который запускается после задержки.

В качестве альтернативы вы могли бы вместо этого запустить код в "doneCallback" в качестве фоновой операции (хотя вы не можете напрямую обновить UIKit из фонового потока, поэтому вам придется отправлять сообщения в основной поток для любых обновлений дисплея). *

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...