我正在使用 AFNetworking 从我的服务器下载文件。它工作正常。但我有一个问题:当我向上或向下滚动时,我的 ProgressView 更新了错误的单元格(UI,而不是数据)。这是我的代码:
我的手机:
AFHTTPRequestOperation *operation;
@property (weak, nonatomic) IBOutlet DACircularProgressView *daProgressView;
- (IBAction)pressDown:(id)sender {
AFAPIEngineer *apiEngineer = [[AFAPIEngineer alloc] initWithBaseURL:[NSURL URLWithString:AF_API_HOST]];
operation = [apiEngineer downloadFile:(CustomObject*)object withCompleteBlock:^(id result) {
} errorBlock:^(NSError *error) {
}];
__weak typeof(self) weakSelf = self;
apiEngineer.afProgressBlock = ^(double progress, double byteRead, double totalByToRead) {
[weakSelf.daProgressView setProgress:progress animated:YES];
};
}
- (void)setDataForCell:(id)object{
}
我的 table :
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
CustomCell *cell = (CustomCell*)[tableView dequeueReusableCellWithIdentifier:NSStringFromClass([CustomCell class])];
cell.backgroundColor = [UIColor clearColor];
CustomObject *aObject = [listObject objectAtIndex:indexPath.row];
[cell setDataForCell: aObject];
return cell;
}
我的下载助手:
- (AFDownloadRequestOperation*)downloadFile:(CustomObject*)aObject
withCompleteBlock:(AFResultCompleteBlock)completeBlock
errorBlock:(AFResultErrorBlock)errorBlock{
NSString *link = URL;
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:link]];
NSString *path = [NSString databasePathWithPathComponent:[NSString stringWithFormat:@"%@.zip", @"noname"]];
AFDownloadRequestOperation *operation = [[AFDownloadRequestOperation alloc] initWithRequest:request targetPath:path shouldResume:YES];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
completeBlock(responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
errorBlock(error);
}];
[operation setProgressiveDownloadProgressBlock:^(AFDownloadRequestOperation *operation, NSInteger bytesRead, long long totalBytesRead, long long totalBytesExpected, long long totalBytesReadForFile, long long totalBytesExpectedToReadForFile) {
float progressF = (float)totalBytesReadForFile / totalBytesExpectedToReadForFile;
self.afProgressBlock(progressF, totalBytesReadForFile, totalBytesExpectedToReadForFile);
}];
[operation start];
return operation;
}
当我在第一个单元格中按下“下载”按钮时:
当我向下滚动然后向上滚动时,它是第二个单元格:
所以,我的问题是:如何更新 UITableViewCell 上的 UIProgressView?我的代码有什么问题?
最佳答案
因为单元格被重复使用,所以您不能只保留对单元格的弱引用并更新单元格的进度 View 。至少,与其使用对 TableView 单元格的弱引用,不如使用索引路径,使用 [tableView cellForRowAtIndexPath:indexPath]
查找正确的单元格(这是一个 UITableView
方法识别与特定 NSIndexPath
相关联的单元格,不应与类似命名的 UITableViewDataSource
方法混淆,我们在其中执行单元格出队/配置逻辑),并更新该单元格的进度 View (假设该单元格甚至可见)。
坦率地说,即使那样也很危险,因为它假设在下载过程中不可能添加或删除单元格。 (这显然不是对应用程序的合理假设/约束。)坦率地说,每次想要更新下载进度时,真的应该回到模型,查找正确的 NSIndexPath
基于有问题的模型对象,然后使用上面的 cellForRowAtIndexPath
模式查找并更新有问题的单元格。
注意,这表明下载请求的发起可能不是由table view cell发起的。就个人而言,我维护了一个模型对象,该对象由要下载的文件数组组成,并将下载队列与其相关联,而不是与单元格相关联(尽管进度处理程序显然会更新单元格)。简而言之,您需要在 UI(例如单元格)和驱动下载的模型之间建立松散耦合的关系。
请注意,许多天真的实现考虑了以上所有要点并决定放弃单元重用以简化问题。我不会强调这一点,但我认为这是一种从根本上被误导的方法。在我看来,应该有一个与 View 对象分开的正确下载模型。
关于ios - UITableViewCell 上的 UIProgressView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29202212/