我使用界面生成器创建了一个自定义单元格,它有两个标签和一个 UIButton。我在 cellForRowAtIndexPath 或 willDisplayCell 中设置每个标签的文本没有问题。但是,设置 UIButton 的图像在任何地方都有问题。我认为这些问题与我不完全理解的单元重用/缓存有关。
这是我当前主要使用 willDisplayCell 的代码,但我也尝试将大部分代码移动到 cellForRowAtIndexPath 并获得相同的结果:
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
UIButton *check = (UIButton*) [cell.contentView viewWithTag:1];
UIButton *check2 = (UIButton*) [cell.selectedBackgroundView viewWithTag:1];
UILabel *from = (UILabel*) [cell.contentView viewWithTag:2];
UILabel *subject = (UILabel*) [cell.contentView viewWithTag:3];
// Configure the cell...
Message *rec = (Message*) Records[indexPath.row];
if(rec.Checked)
check.imageView.image = [UIImage imageNamed:@"Checkedbox.png"];
else
check.imageView.image = [UIImage imageNamed:@"Checkbox.png"];
check2.imageView.image = check.imageView.image;
from.text = rec.From;
subject.text = rec.Subject;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
return cell;
}
在上面的代码中,check2 为 nil,我也尝试过不使用它,但最近才添加它作为修复的尝试。
我基本上是在构建一个消息列表(收件箱)并想要像 GMail 这样的复选框。在复选框按钮的单击事件中,我有:
- (IBAction)CheckClicked:(id)sender
{
UITableViewCell *cell = (UITableViewCell*) [[sender superview] superview];
NSIndexPath *indexPath = [[self tableView] indexPathForCell:cell];
Message *rec = (Message*) Records[indexPath.row];
rec.Checked = !rec.Checked;
[cell setNeedsLayout];
[cell.contentView setNeedsLayout];
[cell setNeedsDisplay];
[cell.contentView setNeedsDisplay];
[self.tableView reloadData];
}
我知道上面所有的 setNeedsLayout 和 setNeedsDisplay 调用都是多余的,我主要只是让它们在那里显示什么不起作用。只有 reloadData 至少会重绘/刷新每个单元格,即使大多数示例说单元格上的 setNeedsLayout 应该有效。
单击时复选框会正确更改,但是如果我选中一个单元格,然后单击以突出显示该单元格,则未选中该复选框,直到视图滚动到屏幕外然后返回。我认为问题与选定与未选定的视图不同有关,但除此之外不知道要检查什么。
编辑:由于大多数教程使用与此类似的代码,这也是我也尝试过的,但在这种用法中,图像永远不会改变,直到单元格滚动并返回屏幕,即使我可以设置断点并看到 cellForRowAtIndexPath 正在在我的点击事件中调用 reloadData 后再次调用每个单元格,并且它正确地将图像设置为检查我检查的项目:
- (IBAction)CheckClicked:(id)sender
{
UITableViewCell *cell = (UITableViewCell*) [[sender superview] superview];
NSIndexPath *indexPath = [[self tableView] indexPathForCell:cell];
Message *rec = (Message*) Records[indexPath.row];
rec.Checked = !rec.Checked;
[self.tableView reloadData];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
// NOTE: In my testing cell is never NULL, so I have no checking here.
UIButton *check = (UIButton*) [cell.contentView viewWithTag:1];
UILabel *from = (UILabel*) [cell.contentView viewWithTag:2];
UILabel *subject = (UILabel*) [cell.contentView viewWithTag:3];
// Configure the cell...
Message *rec = (Message*) Records[indexPath.row];
if(rec.Checked)
check.imageView.image = [UIImage imageNamed:@"Checkedbox.png"];
else
check.imageView.image = [UIImage imageNamed:@"Checkbox.png"];
from.text = rec.From;
subject.text = rec.Subject;
return cell;
}