2014-10-01 2 views
1

У меня есть приложение, которое имеет возможность загружать определенные файлы. Эти файлы отображаются в файле UITableView, и при прослушивании они начинают загружаться.UITableView reloadData блокирует пользовательский интерфейс со многими обновлениями в секунду

Я хотел бы показать ход загрузки в ячейке (например, в процентах). Мой код в настоящее время вызывает уведомления при обновлении хода загрузки.

Проблема в том, что эти обновления прогресса запускаются много (сотни?) Раз в секунду. Если я использую [tableView reloadData] или даже [tableView reloadRowsAtIndexPaths:...], пользовательский интерфейс будет казаться сумасшедшим после начала загрузки, потому что это так часто называют.

Мой код очень минимальный, кроме этого. Я не использую какие-либо необычные методы делегирования UITableView, и я попытался устранить все, кроме обновления метки загрузки в cellForRowAtIndexPath:, но он все еще сильно мешает!

Какие у меня варианты? Я мог бы создать таймер, который обновляет пользовательский интерфейс каждую секунду или около того, чтобы показать ход загрузки, но это кажется взломанным. Пользовательский интерфейс может быть намного лучше! Есть ли любой способ, которым я могу обновить метку загрузки без задержки моего пользовательского интерфейса?

+0

Ну это гораздо лучше, чтобы обновить только точное представление, вид прогрессбара бы то ни было, чем е e полный рабочий стол. В вашем случае я бы добавил это конкретное представление в качестве наблюдателя вашего уведомления, однако вам нужно будет правильно настроить данные, удалить наблюдателей и т. Д. При прокрутке/загрузке новых ячеек в вашей таблице. – deathhorse

ответ

1

Это звучит, как вам нужно, чтобы замедлить поток уведомлений.

Предполагая, что прогресс в диапазоне от 0 до 1, в способе, запускающего уведомление, использовать что-то подобное:

if (floorf(progress*100) == progress*100) { 
    // send notification 
} 

Это только отправить уведомление, чтобы обновить ячейку, когда прогресс, если 1%, 2 % и т.д.

Кроме того, в UITableView, попробуйте только перезарядить видимые ячейки:

if ([[self.tableView indexPathsForVisibleRows] containsObject:indexPath]) { 
    [self.tableView reloadRowsAtIndexPath:@[ indexPath ]]; 
} 
+0

Это, безусловно, потенциальное решение. Однако, если запущено несколько загрузок, обновления обновления могут быть отправлены много раз в секунду из разных файлов. – ttarik

+0

даже при использовании reloadRowsAtIndexPaths :? – Kamchatka

+0

отредактирован с другой помощью – Kamchatka

0

Я хотел бы использовать performSelector: withObject: метод afterDelay, который будет выглядеть как этот

[self performSelector:@selector(updateCell:) withObject:cell afterDelay:0.5]; 

Метод updateCell будет выглядеть как этот

- (void)updateCell:(CustomUITableViewCell *)cell { 
    [cell setNeedsLayout]; 
    if (cell && cell.downloadPercentage < 100) { 
     [self updateCell:cell]; 
    } 
} 

Что это делает, называя updateCell каждые полторы секунды до завершения загрузки. Он вызывает [cell setNeedsLayout] (или вы можете вызвать любой метод, который хотите обновить на дисплее вашей ячейки, чтобы обновить процентную полосу, например [cell setNeedsDisplay] или [cell updateDownloadLabel]), чтобы обновить ячейку, а затем снова вызовет updateCell.

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

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

+0

'setNeedsLayout' не вызывает' cellForRowAtIndexPath', в котором обновляется текстовая метка. Как вы намеревались это работать?Кроме того, какое преимущество выполняет 'performSelector: withObject: afterDelay:' переписать просто вызов функции напрямую? Ваш код также переходит в бесконечный цикл после первого вызова «updateCell:». – ttarik

+0

Заменить setNeedsLayout для reloadRowAtIndexPath или любого другого метода, который вы хотите перезагрузить. Преимущество этого метода заключается в том, что вы можете выполнить его при задержке, что увеличит производительность, поскольку вы не постоянно это делаете. Он не переходит в бесконечный цикл, если cell.downloadPercentage> = 100 – Alex

+0

Прогресс обновления отправляются сотни раз в секунду. Это задержит их на полсекунды, так что через полсекунды они снова начнут посылаться сотни раз в секунду. Если это находится в основном потоке, cell.downloadPercentage никогда не сможет быть обновлен, потому что вы постоянно вызываете 'updateCell:' - бесконечный цикл. – ttarik

Смежные вопросы