К черту всех :)
Мой опыт работы с контроллером 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.referenceProgressBar = progressbar; tempActivity.referenceStatusTextLabel = 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]];
}
}
Меня беспокоит только то, что, поскольку эти объекты работают асинхронно, что, если в какой-то момент табличное представление пользовательского интерфейса решит удалить или повторно использовать ячейки, на которые указывают эти загружаемые объекты? Это не кажется очень безопасным вообще.