本文记录之前帮助朋友开发该功能的填坑之旅,需求为tableView显示图片,图片固定宽度为屏幕宽度高度自适应,保证不失真。
乍看该需求可能并不难甚至简单的很,若API已经给予每个图片的宽高比例,那该功能很容易实现。但是对于一些初创型公司,为减少开发成本,图片的上传下载使用的可能为类似于七牛等云存储服务。图片存储在七牛服务器上,前端传递给后台的仅仅是个图片链接字符串而已。后台人员无法获取图片宽高或因为其他原因无法获取,这时就需要我们自己计算其真实显示高度。
此处省略不断尝试着中的痛苦 ,下面直接说一种可行的方法
这里我们需要使用到SDWebImage中SDWebImageDownloader与SDImageCache这两个类来实现功能,分别为图片下载类于图片缓存类。具体代码如下,假设以获取所需图片网址数组为_picArr。
首先借助SDImageCache进行判断对应图片是否缓存。若已缓存,获取其真实需要显示高度(当前屏幕宽度乘图片比例即可),将获取到的高度存入高度字典中。若不存在缓存,使用SDWebImageDownloader进行下载,在下载结束后同样计算高度并缓存图片。SDWebImageDownloader下载图片为异步,无法保证图片按顺序下载完成,因此这里使用字典存储而非数组。字典键值对存储的即为所对应行应显示的高度。
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return _rowHeightDict.count;
}
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MainTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ReusableID];
UIImage *image = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:_picArr[indexPath.row]];
if (!image) {
cell.photoImageView.image = [UIImage imageNamed:@"placehold"];
} else {
cell.photoImageView.image = image;
}
return cell;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
if (_rowHeightDict[[NSNumber numberWithInteger:indexPath.row]]) {
return [_rowHeightDict[[NSNumber numberWithInteger:indexPath.row]] floatValue];
}
return 200.0;
}
- (void)loadData {
//图片数组
_picArr = [[NSMutableArray alloc]initWithArray:@[@"http://o9kg05vzs.bkt.clouddn.com/ass_199_579_249.jpg",
@"http://o9kg05vzs.bkt.clouddn.com/ass_199_580_504.jpg",
@"http://o9kg05vzs.bkt.clouddn.com/ass_199_576_939.jpg",
@"http://o9kg05vzs.bkt.clouddn.com/ass_199_578_287.jpg",
@"http://o9kg05vzs.bkt.clouddn.com/ass_199_577_411.jpg",
@"http://o9kg05vzs.bkt.clouddn.com/ass_199_574_677.jpg",
@"http://o9kg05vzs.bkt.clouddn.com/ass_199_575_858.jpg",
@"http://o9kg05vzs.bkt.clouddn.com/ass_199_573_546.jpg",
@"http://o9kg05vzs.bkt.clouddn.com/ass_199_572_892.jpg"]];
for (NSInteger i = 0; i < _picArr.count; i++) {
//获取图片网址
NSString *picUrl = _picArr[i];
//根据图片网址获取缓存
UIImage *cachedImage = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:picUrl];
if (cachedImage) {//若存在 计算图片真实需要显示高度 存入字典
float height = cachedImage.size.height * self.view.bounds.size.width / cachedImage.size.width;
[_rowHeightDict setObject:[NSNumber numberWithFloat:height] forKey:[NSNumber numberWithInteger:i]];
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
} else {//不存在缓存 使用SDWebImageDownloader下载
[[SDWebImageDownloader sharedDownloader]downloadImageWithURL:[NSURL URLWithString:picUrl] options:SDWebImageDownloaderProgressiveDownload progress:^(NSInteger receivedSize, NSInteger expectedSize) {
} completed:^(UIImage *image, NSData *data, NSError *error, BOOL finished) {
if (finished) {
//对现在图片进行缓存
[[SDImageCache sharedImageCache] storeImage:image forKey:picUrl toDisk:YES];
float height = image.size.height * self.view.bounds.size.width / image.size.width;
[_rowHeightDict setObject:[NSNumber numberWithFloat:height] forKey:[NSNumber numberWithInteger:i]];
}
dispatch_async(dispatch_get_main_queue(), ^{
[self.tableView reloadData];
});
}];
}
}
}