2012-01-10 4 views
9

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

код должен работать так:

  1. Создать индикатор выполнения (работы)
  2. В новом фоновом режиме: Установить начальный ход 0,25 (работ)
  3. В то же фоновый процесс: Обновление прогресса, идя через петлю (работал в прошивке 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, которые могли сломать его?

ответ

18

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

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

На мой взгляд это выглядит как идеальное применение для блоков. Использование блоков вашего цикла может быть записан следующим образом:

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 
} 
+1

Спасибо, это сработало! Также спасибо за объяснение немного больше, чем просто предоставление рабочего решения :-) – favo

2

Это делает работу в прошивке 5 и самый простой способ для него здесь:

.h файл:

IBOutlet UIProgressView *WhateverYouWantToCallIt; 

. м файла:

[WhateverYouWantToCallIt setProgress:(float) 0.3]; 

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

+0

@ user1791131 он не работает в iOS 5. Основная проблема заключается в том, что он делал изменение пользовательского интерфейса из потока, отличного от основного потока. Любые изменения в пользовательском интерфейсе, сделанные из любого потока, который не является основным потоком, не будут публиковаться. – BigSauce