setProgress больше не обновляет UIProgressView с iOS 5 - PullRequest
9 голосов
/ 10 января 2012

У меня небольшая проблема с индикатором выполнения, так как вышла iOS 5. Приведенный ниже код работал нормально до iOS 5, но в iOS 5 индикатор выполнения больше не отображает новый прогресс, установленный в цикле.

Ожидается, что код будет работать так:

  1. Создать индикатор выполнения (работает)
  2. В новом фоновом процессе: установить начальный прогресс 0,25 (работает)
  3. В том же фоновом процессе: обновлять прогресс во время прохождения цикла (работал в iOS 4)

Вот код для панели init:

// create a progress bar
UIProgressView *progressBar = [[UIProgressView alloc] initWithFrame:CGRectMake(coverSizeX*0.25, coverSizeY - 34.0, coverSizeX*0.5, 9.0)];
progressBar.progress = 0.0;
progressBar.progressViewStyle = UIProgressViewStyleBar;

и в другом потоке он устанавливает начальную точку прогресса на 0,25:

// set an initial progress
[progressBar setProgress: 0.25];

чуть позже обновляется прогресс в цикле для отображения прогресса загрузки:

// within a for-loop:
NSNumber *counterPercentage;
for ( pageDownload = 1; pageDownload < pagesToDownload; pageDownload++ ) {
    counterPercentage = [[NSNumber alloc] initWithFloat: (float)pageDownload / (float)((float)pagesToDownload)];
    [progressBar setProgress: [counterPercentage floatValue]];
    [progressBar performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:YES];
}

… но прогресс не отображается на экране, индикатор выполнения застрял на начальном установленном прогрессе 0,25.

Были ли какие-либо изменения в выпуске iOS 5, которые могли его сломать?

Ответы [ 2 ]

18 голосов
/ 10 января 2012

Я видел много вопросов, подобных этому, после перехода на iOS 5, и я не уверен, почему существует проблема только в iOS 5. Но в основном потому, что я не уверен, почему не было проблема раньше.

В вашем коде вы звоните [progressBar setProgress: [counterPercentage floatValue]]; из фонового потока. Это вызов пользовательского интерфейса, который не должен выполняться из фонового потока. Также вы вызываете setNeedsDisplay, который не является необходимым для обновления progressBar, так как UIProgressView знает, как отобразить себя. Похоже, что в iOS 5 требования к обновлению пользовательского интерфейса стали более строгими, но в любом случае это только лучшие из них.

На мой взгляд, это похоже на идеальное использование для блоков. С помощью блоков ваш цикл for можно записать так:

for ( pageDownload = 1; pageDownload < pagesToDownload; pageDownload++ ) {
        // Other stuff in background
    dispatch_async(dispatch_get_main_queue(), ^{
        progressBar.progress = ((float)pageDownload/(float)pagesToDownload);
    });
        // Other stuff in backgroud
}
2 голосов
/ 01 ноября 2012

Он работает в iOS 5, и самый простой способ сделать это здесь:

.h файл:

IBOutlet UIProgressView *WhateverYouWantToCallIt;

.m файл:

[WhateverYouWantToCallIt setProgress:(float) 0.3];

А там, где написано 0.3, вы можете указать любое значение (от 0 до 1)

...