UITableViewCell上的UIProgressView
我正在使用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{ }
我的桌子:
- (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; }
当我按下第一个单元格中的“下载”button时:
当我向下滚动然后向上滚动,这是第二个单元格:
所以,我的问题是:如何更新UITableViewCell上的UIProgressView? 我的代码有什么问题?
由于单元格被重新使用,您不能只保留对单元格的弱引用并更新单元格的进度视图。 至less,不是对表视图单元使用弱引用,而是使用索引path,使用[tableView cellForRowAtIndexPath:indexPath]
查找正确的单元格(这是一个UITableView
方法,用于标识与特定NSIndexPath
,不应该和名为UITableViewDataSource
方法在我们的单元出队/configuration逻辑中混淆),并更新单元格的进度视图(假设单元格是可见的)。
坦率地说,即使这样也是危险的,因为它假设下载过程中不可能添加或删除单元格。 (这显然不是一个合理的假设/约束放置在应用程序上。)坦率地说,每次想要更新下载进度,真的应该回到模型,查找正确的模型对象的基于NSIndexPath
的问题,然后使用上述cellForRowAtIndexPath
模式来查找并更新有问题的单元格。
请注意,这表示下载请求的启动可能不会由表视图单元启动。 就我个人而言,我维护一个模型对象,它包含一组要下载的文件,并将下载队列与其关联,而不是单元(尽pipe进度处理程序明显更新单元)。 简而言之,您需要UI(例如单元格)与驱动下载的模型之间的松散耦合关系。
请注意,许多天真的实现考虑了上述所有的点,并决定放弃细胞重用,以简化问题。 我不会说这个问题,但我认为这是一个根本性的错误的方法。 在我看来,一个应该有一个适当的模型下载独立于视图对象。
我有一个github上的小项目,基本上做你想要什么不同的风格进度指标。 我build立了一段时间,它使用了Rob提到的方法:表格及其单元格由一个“模型”支持,该模型告诉指定index
处的单元格应该是什么状态。 我也确保细胞被重复使用。 这可能对您有些用处:
- AFNetworking 2.0发送带有URL参数的邮件请求
- 为什么RestKit改变我的响应内容types?
- (cocoa错误3840.)“(字符0附近的值无效)AFNetworking
- 如何使用AFOAuth2Manager自动刷新过期的标记?
- 如何获得由AFNetworking的UIImageView类别存储的caching图像?
- POST请求与JSON正文AFNetworking 2.0
- Swift – 为什么init(编码器)在AFHTTPSessionManager中是必需的?
- 如何将AFHTTPClient,Afnetworking 1.0迁移到2.0
- 取消Afnetworking 2.0中的发布请求