2016-01-23 82 views
0

我将异步加载图像并将其设置为表格视图单元格。问题是我为我的单元格使用自动布局,所以我希望表格视图在设置图像后重绘单元格。重新绘制表格视图单元格而不调用cellForRowAtIndexPath

tableView.rowHeight = UITableViewAutomaticDimension 
tableView.estimatedRowHeight = 300.0 

在通常情况下,我会使用tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Fade),但这种呼吁cellForRowAtIndexPath方法,而这又要求我的图像下载方法。

我试着打电话给tableView.layoutIfNeeded(),cell.layoutIfNeeded(),cell.setNeedsLayout(),没有什么帮助。

我的问题是如何重绘表格视图单元而不调用cellForRowAtIndexPath方法?

回答

0

如果您使用的是UIImageView来显示图像,则不需要重绘该单元格,只需在图像完成下载时设置图像属性即可。

如果您自己在自定义的UIView子类上绘制图像,则可以在该视图上调用setNeedDisplay方法,该方法将视图标记为脏,并将在下一个周期重绘。

但是,最好的方法是改善cellForRowAtIndexPath:并在模型对象中设置downloading标志,并且只有在未设置该标志时才开始下载。

2

这里存在的根本问题是您下载图像的方式。您应该在代码中进行一些记录,并跟踪哪些图像已经下载或已经下载。根据这一点,您可以决定是否应该开始新的下载。 不要试图绕过这个,因为这会在以后给你带来很多痛苦(我从经验中知道)。 最好的方法是拥有某种数据对象,以及另一个可以下载的对象。然后,只要下载完成,该对象就会更新此映像的正确数据对象。然后这个下载者应该告诉你的数据源这个数据对象已经更新了。作为响应,您的dataSource可以重新加载该数据对象的indexPath。通过这种方式,您的数据源永远不用担心下载,并且可以简单地检查数据对象并使用它来设置单元格中的值。如果有图像下载,它将使用它,否则没有图像(或某个占位符可能)。

现在,您可以保留包含作为键的单元格的URL或名称或索引路径的@(YES)或@(NO)值的字典属性。然而,这种方法是天真的,因为它不会很可维护或可移植(对其他viewControllers或您的应用程序的部分),并且索引路径和图像之间不容易转换。请记住,tableViewCells永远不能用作使用某些逻辑的数据源:它们是您拥有其他逻辑将数据放置到其上的终点。这是因为它们被重复使用,基本上不能被信任永远处于某个特定的位置。基于您在indexPaths上的所有工作。 (并使用tableview来获取单元格的indexPath)。

所以,现在你可以在cellForRowAtIndexPath:

NSString * imageURL = .... 
NSNumber * downloading = self.imageDownloads[imageURL]; 
if (!downloading.boolValue) 
{ 
    self.imageDownloads[imageURL] = @(YES); 
    // start your download 
} 

- (void) imageDownloadedForURL: (NSString *) imageURL 
{ 
    self.imageDownloads[imageURL] = @(YES); // this is redundant 
    [self.tableView reloadRowAtIndexPaths: @[indexPathForThisImage]]; 
} 
- (void) imageDownloadForULRFailed: (NSString *) imageURL 
{ 
    self.imageDownloads[imageURL] = @(NO); 
    // trigger a new download? (but be careful not to DDOS your server this way) 
} 
相关问题