1

地狱所有人:)

不幸的是,我在 iOS 中使用 UITablewView 控制器的经验非常有限。我在我的应用程序中需要的是一个 UI 表格视图,其中包含一个自定义单元格,用于当前上传到网络服务器的每个活动上传(视频、音频等)。

这些上传中的每一个都在后台异步运行,并且都应该能够更新它们各自单元格中的诸如 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.referenceStatusTextLabel = cellStatusLabel;

上传活动获取对存储在此单元格中的控件的引用,然后可以自行更新它们。问题是我不知道这是否安全。如果他们引用的单元格被重新使用或从内存中删除,等等怎么办?

是否有另一种方法可以简单地更新底层模型(我的上传活动),然后强制 UI 表格视图重绘更改的单元格?您最终能否将 UITableViewCell 子类化并让他们不断检查上传内容,然后让他们自己上传?

编辑

这是上传活动对象调用其引用 UI 控件的方式:

- (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]];
}
}

我唯一担心的是,由于这些对象异步运行,如果在某个给定点 UI 表格视图决定删除或重新使用这些上传对象指向的单元格怎么办?它似乎一点也不安全。

4

1 回答 1

2

有两种可能性,假设您有一个正在上传的后台进程:

  1. tableview 是一个委托,并实现了一些 uploadProgress 功能
  2. tableview 监听 uploadProgress NSNotifications

第二种更容易实现,只需将监听器的启动/停止放在 viewdidappear/viewdiddissappear 中即可。然后在您的上传中,您可以跟踪进度并发出带有附加用户信息的通知,该用户信息为进度提供整数值。该表具有处理接收到的此通知并重绘单元格的功能。以下是如何将数据添加到 NSNotification 的 userinfo 部分

如果你想变得更漂亮,你可以有一个上传 id 并将其映射到一个单元格索引,然后只重绘那个特定的单元格。这是一个解释如何执行此操作的问题和答案。


恶心的伪代码因为我现在无法访问我的 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)
}

表视图.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
}
于 2012-02-16T18:24:32.687 回答