计算取决于单元格宽度和异步加载的图像的 UITableViewCell 的高度
Posted
技术标签:
【中文标题】计算取决于单元格宽度和异步加载的图像的 UITableViewCell 的高度【英文标题】:Calculating height of the UITableViewCell that is dependent on the cell width and image loaded asynchronously 【发布时间】:2015-02-25 11:44:00 【问题描述】:当UITableViewCell的高度基于表格单元格宽度时,如何正确计算该高度。
我正在尝试将代码放入 heightForRowAtIndexPath 方法中,但尝试在此方法中获取单元格的引用是不可能的,因为它会生成无限循环。在我的单元格中,我正在加载图像并尝试在所有单元格区域中显示它。图像使用查看模式 AspectFit 缩放,因此图像的宽度适合单元格,但我不知道如何计算高度,因此所有图像都可见。仅使用图像高度不是一个好的选择,因为此图像已缩放并适合单元格,因此缩放后其实际高度要小得多。
我正在使用此代码来计算高度,但我不知道如何正确实现它,因此此方法在缩放后返回图像的正确高度并适合单元格内容。
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
NSDictionary *item = self.items[indexPath.row];
UIImage *image = (UIImage *)item[COUPON_IMAGE_BINARY];
if (image)
// here the image is loaded so we can calculate somehow the
// height of the cell after the image is scaled.
// The image is always scaled to the width of the cell.
// How can I get here the cell width?
return image.size.height; // this only works for images that doesn't need any scaling
return 50;
这也是我的方法 cellForRowAtIndex:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
UIImageTableViewCell *cell = (UIImageTableViewCell *)[self.tableView dequeueReusableCellWithIdentifier:itemCellID
forIndexPath:indexPath];
if (cell.imageDownloadTask)
[cell.imageDownloadTask cancel];
NSMutableDictionary *item = self.items[indexPath.row];
if (item[COUPON_IMAGE_BINARY])
cell.customImageView.image = (UIImage *)item[COUPON_IMAGE_BINARY];
return cell;
// image is not loaded yet
NSURL *imageURL = [NSURL URLWithString:item[COUPON_IMAGE_URL]];
if (imageURL)
cell.imageDownloadTask = [self.session dataTaskWithURL:imageURL
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
if (error)
NSLog(@"ERROR: %@", error);
else
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
if (httpResponse.statusCode == 200)
UIImage *image = [UIImage imageWithData:data];
item[COUPON_IMAGE_BINARY] = image; // image is ready to use
dispatch_async(dispatch_get_main_queue(), ^
[self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationNone];
);
else
NSLog(@"Couldn't load image at URL: %@", imageURL);
NSLog(@"HTTP %d", httpResponse.statusCode);
];
[cell.imageDownloadTask resume];
return cell;
我一直在寻找解决方案并阅读了其中近 10 个,但提供的解决方案对我不起作用。有人可以更清楚地说明这个话题吗?我无法使从服务器返回的那些图像缩放,因为后端不支持这些功能。我想做的是在设备中缩放图像并以原始比例显示它与单元格一样宽,因此单元格高度取决于单元格宽度。
【问题讨论】:
【参考方案1】:保持纵横比即可
CGFloat cellHeight = (image.size.height / image.size.width) * tableView.bounds.size.width;
确保将高度限制在某个点
cellHeight = MIN(cellHeight, MAX_HEIGHT);
【讨论】:
谢谢。有用!但是,如果我的手机有附件 Detail Disclosure 怎么办。那么cell没有tableView.bounds那么宽并且cell.contentView的宽度区域小于tableView.bounds.size.width?对我来说真正的挑战是计算计算单元格高度所需的正确单元格宽度。如果我将 Accessory 设置为 None 那么效果很好。 您可以硬编码一个值或创建一个原型单元,将其存储在控制器的属性中并用于计算。有一个similar question 顺便说一句,您不是在后台解压缩图像。图像解压缩是一项繁重的操作(尤其是对于 JPEG),现在它发生在主线程上。有一些框架可以为你处理所有事情,比如我刚刚发布的SDWebImage 和最近的DFImageManager。 一个原型单元的好主意。我还要感谢您的知识分享和关于减压的说明。我会尝试使用 DFImageManager。 谢谢!如果您对 DFImageManager 有任何疑问,只需创建一个带有“dfimagemanager”标签的问题 :)以上是关于计算取决于单元格宽度和异步加载的图像的 UITableViewCell 的高度的主要内容,如果未能解决你的问题,请参考以下文章
自动布局,异步加载图像到 uiimageview (Swift, xCode6)
如何使用 UIImageViewExtension 与 Swift 异步加载图像并防止重复图像或错误图像加载到单元格