Ios UITableViewCell高度在下载图像时调整大小
我正在使用Ios UITableViewCell高度在下载图像时调整大小,ios,dynamic,uitableview,height,afnetworking,Ios,Dynamic,Uitableview,Height,Afnetworking,我正在使用UIImageView+AFNetworkingcategory进行异步映像加载。一切正常,但我尝试了一些方法,但根据下载的图像调整单元格高度时没有成功。我想让图像适应单元格的宽度,但调整高度,但我不知道如何做到这一点。我尝试重新加载下载图像的行,但这只会导致cellforrowatinexpath再次启动并再次设置所有内容,等等。几乎是一个递归 我正在计算新的图像大小差异并将其存储在NSMutableArray中,然后在UIImageView的setImageWithURLReque
UIImageView+AFNetworking
category进行异步映像加载。一切正常,但我尝试了一些方法,但根据下载的图像调整单元格高度时没有成功。我想让图像适应单元格的宽度,但调整高度,但我不知道如何做到这一点。我尝试重新加载下载图像的行,但这只会导致cellforrowatinexpath
再次启动并再次设置所有内容,等等。几乎是一个递归
我正在计算新的图像大小差异并将其存储在NSMutableArray
中,然后在UIImageView的setImageWithURLRequest:Placeholder图像:成功:
的成功块中重新加载该行
我在heightforrowatinexpath
中获得了几行的正确高度,但随后,表开始表现出奇怪的行为,所有内容都重叠了,等等
有什么想法吗
谢谢
编辑
我最终使用了以西基的答案。我还写了一篇关于这个主题的帖子,并制作了一个使用这种技术的示例应用程序
请在上查看。您需要将下载的图像存储在内存或磁盘中,因此下次尝试从此URL获取图像时,您将从缓存中收到图像 因此,如果你这样做,你将不得不这样做:
[tableView beginUpdates];
[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
...
[cell.imageView setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"]
placeholderImage:[UIImage imageNamed:@"placeholder.png"]
success:^(UIImage *image, BOOL cached) {
// save height of an image to some cache
[self.heightsCache setObject:[NSNumber numberWithFloat:imHeight]
forKey:urlKey];
[tableView beginUpdates];
[tableView reloadRowsAtIndexPaths:@[indexPath]
withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];
}
failure:^(NSError *error) {... failure code here ...}];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
// try to get image height from your own heights cache
// if its is not there return default one
CGFloat height = [[self.heightsCache objectForKey:urlKeyFromModelsArrayForThisCell] floatValue];
...
return newHeight;
}
在表视图数据源的这种方法中,您应该返回新单元格的高度:
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
我建议您使用而不是AFNetworking
,因为它可以为您将图像缓存到memcache和磁盘中,并且非常易于使用。因此,如果您决定使用它,您的下载图像代码将如下所示:
[tableView beginUpdates];
[tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
...
[cell.imageView setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"]
placeholderImage:[UIImage imageNamed:@"placeholder.png"]
success:^(UIImage *image, BOOL cached) {
// save height of an image to some cache
[self.heightsCache setObject:[NSNumber numberWithFloat:imHeight]
forKey:urlKey];
[tableView beginUpdates];
[tableView reloadRowsAtIndexPaths:@[indexPath]
withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates];
}
failure:^(NSError *error) {... failure code here ...}];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
// try to get image height from your own heights cache
// if its is not there return default one
CGFloat height = [[self.heightsCache objectForKey:urlKeyFromModelsArrayForThisCell] floatValue];
...
return newHeight;
}
对我来说,这很有效:
检查缓存映像是否可用。如果可用,则将其设置为映像,如果不可用,则下载该映像,然后通过调用重载索引路径重置表的布局
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
static NSString *broadcastTableCellIdentifier = @"BlockbusterTableViewCell";
BlockbusterTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:broadcastTableCellIdentifier];
if (cell == nil) {
cell = [[BlockbusterTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:broadcastTableCellIdentifier];
}
[self configureCell:cell atIndexPath:indexPath];
return cell;
}
-(void)configureCell:(BlockbusterTableViewCell*)cell atIndexPath:(NSIndexPath*)indexPath{
SportData *data = [self.webShared.arrSportsData objectAtIndex:self.selectedEvent];
BroadcastData *broadcastData = [data.broadcastData objectAtIndex:indexPath.row];
NSURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:broadcastData.image]];
AFImageDownloader *downloader = [UIImageView sharedImageDownloader];
id <AFImageRequestCache> imageCache = downloader.imageCache;
UIImage *cacheimage = [imageCache imageforRequest:urlRequest withAdditionalIdentifier:nil];
if (cell.imgBroadcast.image != cacheimage) {
[cell.imgBroadcast setImageWithURLRequest:urlRequest placeholderImage:[UIImage imageNamed:@"placeholder_smaller"] success:^(NSURLRequest * _Nonnull request, NSHTTPURLResponse * _Nullable response, UIImage * _Nonnull image) {
cell.imgBroadcast.image = image;
[self.tableViewBroadcast beginUpdates];
[self.tableViewBroadcast reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
[self.tableViewBroadcast endUpdates];
} failure:^(NSURLRequest * _Nonnull request, NSHTTPURLResponse * _Nullable response, NSError * _Nonnull error) {
}];
}
else{
cell.imgBroadcast.image =cacheimage;
}
cell.lblTitle.text = broadcastData.title;
cell.lblText.text = broadcastData.text;
cell.lblEventDateTime.text = [self eventTime:broadcastData.eventTime];
}
-(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath{
静态NSString*broadcastTableCellIdentifier=@“BlockbusterTableViewCell”;
BlockbusterTableViewCell*单元格=[tableView dequeueReusableCellWithIdentifier:broadcastTableCellIdentifier];
如果(单元格==nil){
cell=[[BlockbusterTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault重用标识符:broadcastTableCellIdentifier];
}
[self-configureCell:cell-atIndexPath:indexPath];
返回单元;
}
-(void)configureCell:(BlockbusterTableViewCell*)单元格atIndexPath:(NSIndexPath*)indexPath{
SportData*data=[self.webShared.arrportsdata objectAtIndex:self.selectedEvent];
BroadcastData*BroadcastData=[data.BroadcastData对象索引:indexath.row];
NSURLRequest*urlRequest=[nsmutableurlRequestWithURL:[nsurlUrlWithString:broadcastData.image]];
AFImageDownloader*downloader=[UIImageView sharedImageDownloader];
id imageCache=downloader.imageCache;
UIImage*cacheimage=[imageCache imageforRequest:urlRequest with AdditionalIdentifier:nil];
if(cell.imgBroadcast.image!=cacheimage){
[cell.imgBroadcast setImageWithURLRequest:urlRequest占位符图像:[UIImage imageNamed:@“占位符”\u较小”]成功:^(NSURLRequest*\u非空请求,NSHTTPURLResponse*\u可空响应,UIImage*\u非空图像){
cell.imgBroadcast.image=图像;
[self.tableview广播开始更新];
[self.tableViewBroadcast重新加载rowsatindexpaths:@[indexath]带rowanimation:UITableViewRowAnimationFade];
[self.tableview广播结束更新];
}失败:^(NSURLRequest*\非空请求,NSHTTPURLResponse*\可空响应,NSError*\非空错误){
}];
}
否则{
cell.imgBroadcast.image=cacheimage;
}
cell.lblTitle.text=broadcastData.title;
cell.lblText.text=broadcastData.text;
cell.lblEventDateTime.text=[self-eventTime:broadcastData.eventTime];
}
谢谢,这是一个很好的建议!顺便说一句,AFNetworking
也处理缓存。无论如何,我让它工作,但tableview滚动现在是非常不稳定的,因为重新加载。也许我会尝试使用sdwebimageprecher
预加载图像。我必须找到一种计算单元格高度的方法,因为我的单元格中还有其他子视图。@你找到问题的完整解决方案了吗?我也遇到了同样的问题。您能提供帮助吗?声明self.heightsCache属性的位置?这只是一个NSMutableDictionary属性,您可以在ViewController.h文件或ViewController.m中使用类别扩展名进行声明。不要忘记在init或viewDidLoad中初始化它。此可变字典将url字符串作为键,NSNumber作为值。@Ezeki我试图以这种方式实现我的tableview,但正如我看到的,有几个缺点:1。内存-执行此操作时,大列表需要大量内存调用[tableView BeginUpdate];[tableView重新加载RowsatindExpaths:@[indexPath]和RowAnimation:UITableViewRowAnimationFade];[tableView EndUpdate]代码>(我看到我的列表有近30mb)2。不太顺