我一直在用头撞墙,并四处寻找解决方案,但无济于事:
我有大量从网络上提取的数据,我正在使用 Loren Brichter 的ABTableViewCell通过在每个单元格的 contentView 内绘制所有内容来使其平稳运行,以避免 UILabels 和 UIImageViews 减慢滚动速度。
这非常适合显示文本,但由于下载图像需要时间,我遇到了图像问题。一旦下载了相应的图像,我似乎无法找到一种方法来强制显示的每个单元格的 contentView 重新绘制自身。我必须指出我不是在绘制标签和图像视图,而只是为了节省内存而绘制 contentView。
现在该表的行为如下:
- 加载:显示文本,无图像
- 向上或向下滚动:一旦单元格移出屏幕,图像最终会显示出来
示例项目在这里
代码:
ABTableViewCell.h
@interface ABTableViewCell : UITableViewCell
{
UIView *contentView;
}
ABTableViewCell.m
- (void)setNeedsDisplay
{
[contentView setNeedsDisplay];
[super setNeedsDisplay];
}
- (void)drawContentView:(CGRect)r
{
// subclasses implement this
}
表格单元布局.h
#import "ABTableViewCell.h"
@interface TableCellLayout : ABTableViewCell {
}
@property (nonatomic, copy) UIImage *cellImage;
@property (nonatomic, copy) NSString *cellName;
表格单元布局.m
#import "TableCellLayout.h"
@implementation TableCellLayout
@synthesize cellImage, cellName;
- (void)setCellName:(NSString *)s
{
cellName = [s copy];
[self setNeedsDisplay];
}
- (void)setCellImage:(UIImage *)s
{
cellImage = [s copy];
[self setNeedsDisplay];
}
- (void)drawContentView:(CGRect)r
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextFillRect(context, r);
[cellImage drawAtPoint:p];
[cellName drawAtPoint:p withFont:cellFont];
}
表视图控制器.m
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
TableCellLayout *cell = (TableCellLayout *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil)
{
cell = [[TableCellLayout alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
cell.cellName = [[array valueForKey:@"name"] objectAtIndex:indexPath.row];
cell.cellImage = [UIImage imageNamed:@"placeholder.png"]; // add a placeholder
NSString *imageURL = [[array valueForKey:@"imageLink"] objectAtIndex:indexPath.row];
NSURL *theURL = [NSURL URLWithString:imageURL];
if (asynchronousImageLoader == nil){
asynchronousImageLoader = [[AsynchronousImages alloc] init];
}
[asynchronousImageLoader loadImageFromURL:theURL];
cell.cellImage = asynchronousImageLoader.image;
return cell;
}
这是图像准备好后 AsynchronousImageLoader 调用的最后一个方法:
- (void)setupImage:(UIImage*)thumbnail {
self.image = thumbnail;
[self setNeedsLayout];
}
一旦下载了行的图像,我只需要正确的方法来告诉我的可见单元格重新绘制自己。我想我应该在最终方法(setupImage)中添加一些东西——但我似乎无法让它按应有的方式工作。想法?非常感谢!
最终编辑:解决方案
是的,正如所怀疑的那样,问题在于调用完成后,没有告诉可见单元重新绘制并更新到下载的图像。
我使用以下答案提供的帮助来组合一个适合我需求的解决方案:
在异步图片下载器调用的 final 方法中添加了一个回调:
AsyncImageView.m
- (void)setupImage:(UIImage*)thumbnail {
self.cellImage = thumbnail;
[cell setNeedsDisplay];
}
注意:我还在图像下载器类的初始化中设置了一个本地占位符图像,只是为了美化一点。
然后在我的 cellForRowAtIndexPath 中:
NSURL *theURL = [NSURL URLWithString:imageURL];
AsyncImageView *aSync = [[AsyncImageView alloc] initWithFrame:CGRectMake(0, 0, 20, cell.bounds.size.height)];
[aSync loadImageFromURL:theURL];
cell.cellImageView = aSync;
return cell;
可能还有一两个其他调整,但这些是这里的主要问题。再次感谢 SO 社区!