我有一个带有 customCell 的 TableView,它具有以下属性:
@interface CustomTableViewCell : UITableViewCell
@property (weak, nonatomic) IBOutlet UIImageView *image;
@property (weak, nonatomic) IBOutlet UILabel *nameOfImage;
@property (weak, nonatomic) IBOutlet UIButton *start;
@property (weak, nonatomic) IBOutlet UIButton *stop;
@property (weak, nonatomic) IBOutlet UIProgressView *progressView;
@property (weak, nonatomic) IBOutlet UILabel *realProgressStatus;
在表格 View 中 - 当用户按下开始按钮时 - 下载图像,以及带有 realProgressStatus 的 progressView 反射(reflect)当前情况。在这个阶段一切都很完美,但是当滚动表格 View 并返回到单元格时 - 已经用数据完成了 - 所有信息都消失了(除了 nameOfImage,我单独设置了它)。
我在 CustomTableViewCell 类中实现了下一个方法:
-(void)prepareForReuse
{
[super prepareForReuse];
self.progressView.progress = 0.1;
self.realProgressStatus.text = @"";
self.image.image = [UIImage imageNamed:@"placeholder"];
}
我实现了新属性 NSMutableSet self.tagsOfCells,我在其中保存了已下载图像的单元格数量。
我试图在 TableView 方法中进行更改,但效果是一样的:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString* PlaceholderCellIdentifier = @"Cell";
CustomTableViewCell *customCell = [tableView dequeueReusableCellWithIdentifier:PlaceholderCellIdentifier forIndexPath:indexPath];
customCell.delegate = self;
customCell.cellIndex = indexPath.row;
if (!customCell)
{
customCell = [[CustomTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:@"cell"];
}
else
{
NSNumber *myNum = [NSNumber numberWithInteger:indexPath.row];
if (![self.tagsOfCells containsObject:myNum])
{
NSLog(@"Row: %ld",(long)indexPath.row);
UIImage *img = [UIImage imageNamed:@"placeholder"];
customCell.realProgressStatus.text = @"";
customCell.progressView.progress = 0.1;
customCell.image.image = img;
[customCell setNeedsLayout];
}
}
if ( indexPath.row % 2 == 0 )
customCell.backgroundColor = [UIColor grayColor];
else
customCell.backgroundColor = [UIColor darkGrayColor];
customCell.nameOfImage.text = self.names[indexPath.row];
return customCell;
}
编辑:
我在下载图像期间以一种方法填充 self.tagsOfCells,方法如下:
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
self.customCell.realProgressStatus.text = @"Downloaded";
UIImage *img = [UIImage imageWithData:self.imageData];
self.customCell.image.image = img;
self.customCell.tag = self.selectedCell;
[self.savedImages setObject:img forKey:self.customCell.nameOfImage.text];
NSNumber *myNum = [NSNumber numberWithInteger:self.selectedCell];
[self.tagsOfCells addObject:myNum];
}
提前感谢您的任何帮助或建议。
最佳答案
不应在 prepareForReuse 函数中发生与内容相关的操作。
https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITableViewCell_Class/#//apple_ref/occ/instm/UITableViewCell/prepareForReuse
If a UITableViewCell object is reusable—that is, it has a reuse identifier—this method is invoked just before the object is returned from the UITableView method dequeueReusableCellWithIdentifier:. For performance reasons, you should only reset attributes of the cell that are not related to content, for example, alpha, editing, and selection state. The table view's delegate in tableView:cellForRowAtIndexPath: should always reset all content when reusing a cell. If the cell object does not have an associated reuse identifier, this method is not called. If you override this method, you must be sure to invoke the superclass implementation.
已编辑
Alfie 是对的,从
cellForRowAtIndexPath
返回后没有调用 prepareForReuse我会尝试的第一件事是编辑代码
if (!customCell)
{
customCell = [[CustomTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:@"cell"];
}
else
{
NSNumber *myNum = [NSNumber numberWithInteger:indexPath.row];
if (![self.tagsOfCells containsObject:myNum])
{
NSLog(@"Row: %ld",(long)indexPath.row);
UIImage *img = [UIImage imageNamed:@"placeholder"];
customCell.realProgressStatus.text = @"";
customCell.progressView.progress = 0.1;
customCell.image.image = img;
[customCell setNeedsLayout];
}
}
到以下
if (!customCell)
{
customCell = [[CustomTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:@"cell"];
}
NSNumber *myNum = [NSNumber numberWithInteger:indexPath.row];
if (![self.tagsOfCells containsObject:myNum])
{
NSLog(@"Row: %ld",(long)indexPath.row);
UIImage *img = [UIImage imageNamed:@"placeholder"];
customCell.realProgressStatus.text = @"";
customCell.progressView.progress = 0.1;
customCell.image.image = img;
[customCell setNeedsLayout];
}
这确实不是一项昂贵的操作,最好将这个逻辑放在一个地方。特别是因为你摆脱了 prepareForReuse,这应该改变。
当你滚动出去,然后回来找不到你的数据的原因是
cellForRowAtIndexPath
再次被调用,这会导致默认数据覆盖您刚刚添加的新数据。您可能希望拥有一个底层数据结构并从那里检索数据。
我会做什么:
例如,您可以保留一个可变列表
NSMutableArray* tableData = [[NSMutableArray alloc] init];
将每一行的图像数据添加到数组中
[tableData add:imageData];
然后显示它添加
cellForRowAtIndexPath
customCell.image.image = [tableData objectAtIndex:[indexPath row]];
这将是用数据填充 UITableView 的正常做法。这样,即使您滚动离开 tableData 也会保持不变,从而产生一致的数据。
备注
我还将使用
NSURLSession
异步调用新数据来自 在 内如果我必须实现这个单元格。只是一个建议=)
关于ios - prepareForReuse 之后的 UITableView - Cell 中的所有数据都消失了,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36253836/