обновление ячейки представления таблицы интерфейса со статусом загрузки - iOS - PullRequest
1 голос
/ 16 февраля 2012

Ад всем:)

Мой опыт работы с контроллером UITablewView в iOS, к сожалению, весьма ограничен.Что мне нужно в моем приложении, так это представление таблицы пользовательского интерфейса, которое содержит одну настраиваемую ячейку для каждой активной загрузки, которая в данный момент загружается на веб-сервер (видео, аудио и т. Д.).

Каждая из этих загрузок выполняется асинхронно в фоновом режиме,и все должны иметь возможность обновлять такие вещи, как UILabels в соответствующих ячейках, что-то говорит о прогрессе обновления в процентах и ​​т. д.

Теперь я нашел решение, которое работает.Проблема в том, что я не знаю, действительно ли это безопасно или нет.Исходя из собственного заключения, я не думаю, что это так.Я просто получаю ссылку на UIViews из создаваемой ячейки, а затем сохраняю эти ссылки в загружаемых объектах, чтобы они могли изменять текст метки и так далее.

Мое собственное решение

-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
 static NSString *CustomCellIdentifier = @"CustomCell";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: CustomCellIdentifier];

if (cell == nil)
{
    NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"UploadCellView" owner:self options:nil];

    if ([nib count] > 0)
    {
        cell = customCell;
    }
    else
    {
        NSLog(@"Failed to load CustomCell nib file!");
    }
}

NSUInteger row = [indexPath row];
UploadActivity *tempActivity = [[[ApplicationActivities getSharedActivities] getActiveUploads] objectAtIndex:row];

UILabel *cellTitleLabel = (UILabel*)[cell viewWithTag:titleTag];
cellTitleLabel.text = tempActivity.title;

UIProgressView *progressbar = (UIProgressView*)[cell viewWithTag:progressBarTag];
[progressbar setProgress:(tempActivity.percentageDone / 100) animated:YES];

UILabel *cellStatusLabel = (UILabel*)[cell viewWithTag:percentageTag];

[cellStatusLabel setText:[NSString stringWithFormat:@"Uploader - %.f%% (%.01fMB ud af %.01fMB)", tempActivity.percentageDone, tempActivity.totalMBUploaded, tempActivity.totalMBToUpload]];

tempActivity.referencingProgressBar = progressbar;
tempActivity.referencingStatusTextLabel = cellStatusLabel;

return cell;
}

Как вы можете заметить, именно здесь я думаю, что я делаю что-то не достаточно хорошее: tempActivity.referencingProgressBar = progressbar;tempActivity.referencingStatusTextLabel = cellStatusLabel;

Операции загрузки получают ссылку на элементы управления, хранящиеся в этой ячейке, и затем могут сами обновлять их.Проблема в том, что я не знаю, безопасно это или нет.Что если ячейка, на которую они ссылаются, будет повторно использована или удалена из памяти и т. Д.?

Есть ли другой способ, которым вы можете просто обновить базовую модель (мои действия по загрузке) и затем принудительно настроить пользовательский интерфейстабличное представление, чтобы перерисовать измененные ячейки?Не могли бы вы в конечном итоге создать подкласс UITableViewCell и позволить им постоянно проверять загрузку, а затем заставлять их загружать сами?

РЕДАКТИРОВАТЬ

Это то, как объекты активности загрузки вызываютссылки на элементы управления пользовательского интерфейса:

- (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten
totalBytesWritten:(NSInteger)totalBytesWritten
totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite
{
if (referencingProgressBar != nil)
{
    [referencingProgressBar setProgress:(percentageDone / 100) animated:YES];
}

if (referencingStatusTextLabel != nil)
{
    [referencingStatusTextLabel setText:[NSString stringWithFormat:@"Uploader - %.f%% (%.01fMB ud af %.01fMB)", percentageDone, totalMBUploaded, totalMBToUpload]];
}
}

Меня беспокоит только то, что, поскольку эти объекты работают асинхронно, что, если в какой-то заданной точке табличное представление пользовательского интерфейса решит удалить или повторно использовать ячейки, на которые указывают эти загружаемые объектык?Это не совсем безопасно.

1 Ответ

2 голосов
/ 16 февраля 2012

Существует две возможности, если у вас есть фоновый процесс, который загружает:

  1. Табличное представление является делегатом и реализует некоторую функцию uploadProgress
  2. Табличное представление прослушивает uploadProgress NSNotifications

Вторую проще реализовать, просто поместите старт / стоп слушателей в viewdidappear / viewdiddissappear.Затем в вашей загрузке вы можете отслеживать прогресс и отправлять уведомление с прикрепленной информацией о пользователе, которая дает целочисленное значение для прогресса.В таблице есть функция, которая обрабатывает это полученное уведомление и перерисовывает ячейки. Вот как добавить данные в часть userinfo NSNotification .

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


Отвратительный псевдокод, поскольку у меня сейчас нет доступа к моей среде разработки IOS

загрузитьфункция:

uploadedStuff{
  upload_id = ... // unique i, maps to row in table somehow
  byteswritten = ...
  bytestotal = ....
  userinfo = new dict
  userinfo["rowid] = upload_id
  userinfo["progress"] = (int)byteswritten/bytestotal
  sendNotification("uploadprogress",userinfo)
}

tableview.m:

viewdidappear{
  listenForNotification name:"uploadprogress" handledBy:HandleUploadProgress
}

viewdiddisappear{
  stoplisteningForNotification name:"uploadprogess"
}

HandleUploadProgess:NSNotification notification {
 userinfo = [notification userinfo]
 rowId = [userinfo getkey:"rowId"]
 progress = [userinfo getkey:"rowId"]
 // update row per the link above
}
...