该问题未指定不同图像大小的所需行为。单元格应该变得更高以适应,还是只是单元格内的图像视图(看起来像代码中的按钮)?
但是我们应该暂时搁置这个问题,并处理代码中更严重的问题:它从cellForRowAtIndexPath 发出一个无人看管的网络请求。结果,(a)用户来回滚动将产生许多冗余请求,并且(b)用户快速滚动很长一段路将生成一个请求,该请求在启动它的单元格消失时被满足 - 重用为单元格换另一行。
为了解决 (a),数据源应该缓存获取的图像,并且只请求那些尚未收到的图像。为了解决 (b),完成块不应直接引用单元格。
一个简单的缓存应该是这样的:
@property(strong,nonatomic) NSMutableDictionary *images;
// initialize this when you initialize your model
self.images = [@{} mutableCopy];
// move the network code into its own method for clarity
- (void)imageWithPath:(NSString *)path completion:(void (^)(UIImage *, NSError *))completion {
if (self.images[indexPath]) {
return completion(self.images[indexPath], nil);
}
NSURL *imageURL = [NSURL URLWithString:path];
NSURLRequest *request = [NSURLRequest requestWithURL:imageURL];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if (!error){
UIImage *image = [UIImage imageWithData:data];
self.images[indexPath] = image;
completion(image, nil);
} else {
completion(nil, error);
}
}];
}
现在,我们通过首先检查 cellForRowAtIndexPath 中缓存中的图像来解决多请求问题。
UIImage *image = self.images[indexPath];
if (image) {
[cell.CellImg setBackgroundImage:image forState:UIControlStateNormal];
} else {
// this is a good place for a placeholder image if you want one
[cell.CellImg setBackgroundImage:nil forState:UIControlStateNormal];
// presuming that 'img' is a string from your mode
[self imageWithPath:img completion:^(UIImage *image, NSError *error) {
// the image is ready, but don't assign it to the cell's subview
// just reload here, so we get the right cell for the indexPath
[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}];
}
还要注意在完成块中没有做什么......我们通过不引用单元来修复单元重用。相反,知道图像现在已缓存,我们重新加载 indexPath。
回到图像大小:大多数应用程序喜欢看到表格视图单元格随着可变高度子视图变高或变短。如果是这种情况,那么您根本不应该对该子视图施加高度限制。相反,将其顶部和底部边缘约束到单元格的内容视图(或将其包含在子视图链中,这些子视图相互约束顶部和底部并包含单元格的顶部和底部边缘的最顶部和最底部子视图)。然后(我认为在 iOS 5+ 中),这将允许您的单元格使用该子视图约束链更改高度...
self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.estimatedRowHeight = // your best guess at the average height here