我有一个带有customCell的TableView,它有下一个属性:
MouseListener
在表格视图中 - 当用户按下开始按钮 - 下载图像时,以及带有realProgressStatus的progressView反映当前情况。在这个阶段,一切都很完美,但是当滚动表视图并返回到单元格时 - 已经满足数据 - 所有信息都消失了(除了nameOfImage,我单独设置)。 我在CustomTableViewCell类中实现了next方法:
@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;
我实现了新属性NSMutableSet self.tagsOfCells,其中我保存了已下载图像的单元格数。 我尝试在TableView方法中进行更改,但效果是相同的:
-(void)prepareForReuse
{
[super prepareForReuse];
self.progressView.progress = 0.1;
self.realProgressStatus.text = @"";
self.image.image = [UIImage imageNamed:@"placeholder"];
}
编辑:
我在下载图片时在其中一个方法中填充self.tagsOfCells,这是方法:
- (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;
}
提前感谢您的任何帮助或建议。
答案 0 :(得分:3)
与prepare内容相关的操作不应出现在prepareForReuse函数中。
如果UITableViewCell对象是可重用的 - 也就是说,它具有重用标识符 - 在从UITableView方法dequeueReusableCellWithIdentifier:返回对象之前调用此方法:出于性能原因,您应该仅重置与内容无关的单元格属性,例如,alpha,编辑和选择状态。 tableView:cellForRowAtIndexPath:中的表视图委托应始终在重用单元格时重置所有内容。如果单元对象没有关联的重用标识符,则不会调用此方法。如果重写此方法,则必须确保调用超类实现。
<强>被修改强>
Alfie是对的,从cellForRowAtIndexPath
我要尝试的第一件事是编辑代码
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
异步调用新数据。只是一个建议=)
答案 1 :(得分:1)
我认为这与您使用prepareForReuse
无关。几件事看起来很腥。
您需要先知道自己手机上的delegate
和cellIndex
属性,然后才知道它是否为零。如果它为零则则永远不会设置这些属性。
我也不认为你需要else
条款。它所包含的逻辑与细胞是否可以出列无关。它与配置非零单元有关。
您问题中缺少的部分是在哪里填充tagsOfCells
对象?那段代码很重要。如果您未在cellForRowAtIndexPath
中设置标记,则您的数据似乎会不同步,这会导致您的单元格配置错误。
请尝试以下代码:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString* PlaceholderCellIdentifier = @"Cell";
CustomTableViewCell *customCell = [tableView dequeueReusableCellWithIdentifier:PlaceholderCellIdentifier forIndexPath:indexPath];
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];
}
customCell.delegate = self;
customCell.cellIndex = indexPath.row;
customCell.nameOfImage.text = self.names[indexPath.row];
if (indexPath.row % 2 == 0)
{
customCell.backgroundColor = [UIColor grayColor];
}
else
{
customCell.backgroundColor = [UIColor darkGrayColor];
}
return customCell;
}
修改强>
关于另一个答案中的信息。配置单元格后,未调用prepareForReuse
。在您配置单元格之前调用dequeueReusableCell
并因此调用时调用它。我不相信prepareForReuse
是问题所在。
答案 2 :(得分:0)
看起来您没有使用界面构建器的原型单元格,因此您使用了错误的出列可重用单元格方法。在你的情况下正确的一个没有索引路径参数,例如。
CustomTableViewCell *customCell = [tableView dequeueReusableCellWithIdentifier:PlaceholderCellIdentifier];
正如其他人所说,在你为自定义单元格分配初始化之后你需要移动你的2行初始化,因为它之前没有。例如,您需要将单元格出列,如果没有,则创建一个单元格。然后在您拥有有效实例的情况下在单元格上设置参数。