Ios 为每个UITableViewCell设置UIButton.imageView.image
我使用interface builder创建了一个自定义单元格,它有两个标签和一个UIButton。我可以在CellForRowatineXpath或willDisplayCell中设置每个标签的文本。但是,设置UIButton的图像在这两个地方都有问题。我认为这些问题与我不完全理解的单元重用/缓存有关 以下是我当前主要使用willDisplayCell的代码,但我也尝试将大部分代码移动到CellForRowatineXpath,结果相同:Ios 为每个UITableViewCell设置UIButton.imageView.image,ios,xcode,uitableview,Ios,Xcode,Uitableview,我使用interface builder创建了一个自定义单元格,它有两个标签和一个UIButton。我可以在CellForRowatineXpath或willDisplayCell中设置每个标签的文本。但是,设置UIButton的图像在这两个地方都有问题。我认为这些问题与我不完全理解的单元重用/缓存有关 以下是我当前主要使用willDisplayCell的代码,但我也尝试将大部分代码移动到CellForRowatineXpath,结果相同: - (void)tableView:(UITableV
- (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调用都是多余的,我通常只是把它们放在那里,以显示哪些不起作用。只有重新加载数据至少会重新绘制/刷新每个单元格,即使大多数示例都说单元格上的setNeedsLayout应该起作用
当单击时,复选框会正确更改,但是如果我选中一个单元格,然后单击以突出显示该单元格,则复选框将被取消选中,直到视图滚动到屏幕外,然后返回。我假设问题与“选定”和“未选定”存在不同的视图有关,但除此之外,我不确定要检查什么
编辑:由于大多数教程使用与此类似的代码,我也尝试了以下方法,但在这种用法中,图像在单元格被滚动到屏幕上之前不会改变,即使我可以设置断点,并看到在单击事件中调用reloadData后,会再次为每个单元格调用cellForRowAtIndexPath,对于我选中的项目,它正确地将图像设置为选中:
- (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;
}
你试过了吗
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = nil;
// Try to dequeue
cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
// If nothing to dequeue, create your CustomCell
if(!cell){
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:nil options:nil];
for(id currentObject in topLevelObjects){
if([currentObject isKindOfClass:[CustomCell class]]){
cell = (CustomCell *)currentObject;
break;
}
}
}
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;
return cell;
}
不使用
表格视图:willDisplayCell:forrowatinexpath:
?然后每次单击[self.tableView reloadData]调用code>,导致tableView刷新并调用cellforrowatinedexpath:
用于所有可见的索引路径…不确定这是否是一个好的答案,但它似乎可以工作,并且可能是Apple预期的方式
我是从另一个SO答案中得到这个想法的,他们为每种不同的风格使用了多个原型
所以我在IB中创建了两个原型单元,一个带有选中图像,另一个带有未选中图像。然后将我的代码更新为:
- (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
{
Message *rec = (Message*) Records[indexPath.row];
UITableViewCell *cell;
if(rec.Checked)
cell = [tableView dequeueReusableCellWithIdentifier:@"CheckedCell"];
else
cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
UILabel *from = (UILabel*) [cell.contentView viewWithTag:2];
UILabel *subject = (UILabel*) [cell.contentView viewWithTag:3];
from.text = rec.From;
subject.text = rec.Subject;
return cell;
}
我能想到的只是“重用”单元支持某些更改,但不支持其他更改。因此,它支持UILabel控件中的不同文本,但不支持UIButton控件中的不同图像。我曾读到有人发现某些属性(如背景颜色和字体样式)存在问题,因此这可能只是这些方面的另一个问题。是的,但为了确保我现在会重试,因为代码有点变化……我将刚尝试过的代码添加到我的原始帖子中,结果不同,但仍然不起作用。在我的代码中,dequeueReusableCellWithIdentifier从不返回null,我认为这是应该的,因为单元格是在IB中定义的,而不是在运行时添加的。也许这就是问题所在,不确定,但是添加额外的代码应该不会有帮助,因为它在我的情况下永远不会运行,因为从不为NULL。我只是看到了你的编辑,但我不明白。您的意思是clickEvent有效地改变了图像,同时您必须上下滚动才能看到效果?CheckClicked函数中的重载数据调用导致对每个可见单元格再次调用cellForRowAtIndexPath,通过调试器可以正确地显示我的代码,设置选中/未选中的图像,但iOS 6.0模拟器上的显示没有更新。所以我的代码似乎工作正常,但结果并不是我所期望的。哦,我明白了。所有对象都将更新,但显示屏上没有任何更改。真倒霉我相信你的变通办法是我当时唯一能想到的办法,对不起!