UIProgressView не обновляется в цикле - PullRequest
1 голос
/ 13 ноября 2011

Я загружаю файл и хотел бы показать прогресс в UIProgressView. Я могу установить начальное значение с помощью:

[loadingProgressView setProgress: 0.00];

.. в viewDidLoad это прекрасно работает.

Единственное, что я хочу сделать, - это добавить 0.1 в столбец каждого цикла, но он не обновляется:

 while (eOF != 99999) {

    ...

    [loadingProgressView setProgress:loadingProgressView.progress + 0.10];

 }

Я проверил, но ничего не нашел, просто обновляя бар при каждом цикле.

Кто-нибудь, кто может поделиться некоторыми советами по этому поводу?

--- UPDATE ---

попробовал это безуспешно:

while (eOF != 99999) {

    ...

    [loadingProgressView setProgress:loadingProgressView.progress + 0.10];
    [[NSRunLoop currentRunLoop] runUntilDate:[NSDate date]];

 }

Ответы [ 5 ]

11 голосов
/ 13 ноября 2011

Вы перебираете цикл while, блокируя основной поток, элементы пользовательского интерфейса не смогут обновиться, пока основной поток не станет доступным.Лучший способ обойти это - запустить этот код в фоновом потоке (вызывая пользовательский интерфейс в основном потоке).

Или (я не уверен в этом, см. это обсуждение ) Вы позволяете основному потоку передышку, вызывая

NSDate* futureDate = [NSDate dateWithTimeInterval:0.001 sinceDate:[NSDate date]];
[[NSRunLoop currentRunLoop] runUntilDate:futureDate];
4 голосов
/ 14 ноября 2011

МОЕ ФИНАЛЬНОЕ РЕШЕНИЕ

Во-первых, если это неправильный способ закрыть эту тему, я прошу прощения!

После долгих испытаний и исследований я, наконец, сделал следующее, чтобы отобразить мой UIProgressView:

while (eOF != 99999) {

    ...

    [NSThread sleepForTimeInterval: 0.01];
    [self performSelectorOnMainThread: @selector(makeMyProgressBarMoving) withObject: nil waitUntilDone: NO];

 }



-(void)makeMyProgressBarMoving {
    float actual = [loadingProgressView progress];
    loadingProgressView.progress = actual + receivedData;
} 

... и теперь, наконец, все работает отлично: -)

Однако, спасибо за помощь, я многому научился из этого.

4 голосов
/ 13 ноября 2011

Пользовательский интерфейс обновляется как часть цикла выполнения, что не произойдет во время цикла while. Вы можете запустить его, позвонив по этому номеру:

[[NSRunLoop currentRunLoop] runUntilDate:[NSDate date]];

Это заставляет цикл обновлять пользовательский интерфейс и т. Д.

2 голосов
/ 09 января 2012

Полагаю, что в этом случае правильный способ - использовать блоки и многопоточность. Ваш код будет выглядеть так:

dispatch_queue_t myQueue = dispatch_queue_create("my queue", NULL);
dispatch_async(myQueue, ^
{
    while (eOF != 99999) {

        // ...
        // your code
        // ...

        dispatch_async(dispatch_get_main_queue(), ^{
            loadingProgressView.progress += 0.10;
        });
    }
});
dispatch_release(myQueue);

Подробнее см. Здесь лекции Пола Хегарти http://itunes.apple.com/itunes-u/ipad-iphone-application-development/id480479762 лекция 10, очень четкое объяснение и учебное пособие.

0 голосов
/ 13 ноября 2011

Несколько вещей, которые вы можете попробовать.

Сначала проверьте, чтобы узнать, каково текущее значение вашего UIProgressView (прежде чем увеличивать его)

то есть

float progress = loadingProgressView.progress;

[loadingProgressView setProgress: progress+0.10];

(установите точку останова на этой строке, чтобы увидеть, увеличивается ли прогресс)

...