带有进度条下载更新的自定义 UITableViewCell
Posted
技术标签:
【中文标题】带有进度条下载更新的自定义 UITableViewCell【英文标题】:Custom UITableViewCell with Progress Bar download update 【发布时间】:2014-01-15 09:28:56 【问题描述】:我正在尝试使用进度条加载更新每个表格单元格,但我被卡住了。 我为具有以下属性的表格视图创建了一个自定义单元格:
@interface OFPTableCell : UITableViewCell
@property (nonatomic, weak) IBOutlet UILabel *textLabel;
@property (nonatomic, weak) IBOutlet UILabel *detailTextLabel;
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@property (weak, nonatomic) IBOutlet UIProgressView *progressView;
@end;
在@synthesize 它们之后,现在我在每个表格单元格中都有一个预期的进度条。
问题是,当我尝试使用加载进度条更新第一个单元格时,它什么也不做,或者设置为 0 或完整的进度条。 请注意,下载过程运行正常。
您可能会在下面找到我尝试更新进度条的代码:
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten
totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite: (int64_t)totalBytesExpectedToWrite
dispatch_async(dispatch_get_main_queue(), ^
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
OFPTableCell *cell = (OFPTableCell*)[self tableView:self.tableViewCache cellForRowAtIndexPath:indexPath];
cell.progressView.progress=(double)totalBytesWritten / (double)totalBytesExpectedToWrite;
);
下面是 cellForRowAtIndexPath 方法:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
OFPTableCell *cell = [self.tableViewCache dequeueReusableCellWithIdentifier:@"Cell"];
OFPVideoDetails *vd = [someArray objectAtIndex:indexPath.row];
cell.textLabel.text=vd1;
cell.detailTextLabel.text=vd2;
CGSize size = 65,53;
cell.imageView.image =[self imageWithImage:[UIImage imageWithContentsOfFile:vd.imageUrl] scaledToSize:size];
cell.delegate = self;
return cell;
【问题讨论】:
【参考方案1】:直接调用方法tableView:cellForRowAtIndexPath:
是非常糟糕的做法,因为该单元格可能同时不存在,并且可能是您遇到的错误的原因。
基本上你应该用另一种方式来做:添加一个双精度数组:
double progressValues[30]; // 30 is the count of rows on your tableView, you can set the size dynamically
并像这样使用它:
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten
totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:
(int64_t)totalBytesExpectedToWrite
dispatch_async(dispatch_get_main_queue(), ^
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
OFPTableCell *cell = (OFPTableCell*)[self tableView:self.tableViewCache cellForRowAtIndexPath:indexPath];
progressValues[indexPath.row] = (double)totalBytesWritten / (double)totalBytesExpectedToWrite;
[self.tableViewCache reloadData];
);
并在 dataSource 方法中添加这个字符串:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
//... your code...
cell.progressView.progress = progressValues[indexPath.row];
// ...
return cell;
【讨论】:
还有一个问题,而不是 [self.tableViewCache reloadData];我可以使用 [self.tableViewCache reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone]; ? 是的,当然你最好只重新加载一行,它会在当前时间发生变化。我在上面写的只是一般想法,没有考虑到这些细节:) 我得到 nil 在:cell.progressView.progress = progressValues[indexPath.row]; 但是如何识别我们正在为哪个单元格显示进度视图?【参考方案2】:您应该在 OFPVideoDetails 中保留 (double)totalBytesWritten / (double)totalBytesExpectedToWrite 的值(在 OFPVideoDetails 中添加一个属性“progress”)。
然后重新加载- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten
totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite: (int64_t)totalBytesExpectedToWrite
中的单元格
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
OFPTableCell *cell = [self.tableViewCache dequeueReusableCellWithIdentifier:@"Cell"];
OFPVideoDetails *vd = [someArray objectAtIndex:indexPath.row];
cell.textLabel.text=vd1;
cell.detailTextLabel.text=vd2;
CGSize size = 65,53;
cell.imageView.image =[self imageWithImage:[UIImage imageWithContentsOfFile:vd.imageUrl] scaledToSize:size];
cell.progressView.progress = vd.progress;
cell.delegate = self;
return cell;
【讨论】:
什么是 OFPVideoDetails?【参考方案3】:对于 Swift 4.2
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64)
DispatchQueue.main.async(execute:
let indexPath = IndexPath(row: 0, section: 0)
let cell = self.tableView(self.tableViewCache, cellForRowAt: indexPath) as? OFPTableCell
progressValues[indexPath.row] = Double(totalBytesWritten) / Double(totalBytesExpectedToWrite)
self.tableViewCache.reloadData()
)
【讨论】:
以上是关于带有进度条下载更新的自定义 UITableViewCell的主要内容,如果未能解决你的问题,请参考以下文章