UITableView 每个单元格中有多个项目

Posted

技术标签:

【中文标题】UITableView 每个单元格中有多个项目【英文标题】:UITableView with multiple items in each cell 【发布时间】:2011-03-21 15:42:03 【问题描述】:

我有一个表格视图,我试图在其中放置一个带有图像和标签的按钮。我想在单击后更改按钮的图像。

代码如下:

- (UITableViewCell *)tableView:(UITableView *)_tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 

static NSString *CellIdentifier = @"Cell";
checkedImg = [UIImage imageNamed:@"buttonUnChecked1.png"];

UITableViewCell *cell = [_tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) 
    cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];



//Set up the cell...
NSString *cellValue = [suggestions objectAtIndex:indexPath.row];

cell.selectionStyle = UITableViewCellSelectionStyleNone;

check = [UIButton buttonWithType:UIButtonTypeCustom];
check.frame=CGRectMake(0,35,20,20);
[check setImage:checkedImg forState:UIControlStateNormal];
[check addTarget:self action:@selector(checkClicked:) forControlEvents: UIControlEventTouchUpInside];
[cell.contentView addSubview:check];

cellContent = [[UILabel alloc]initWithFrame:CGRectMake(40,32,500,25)];
cellContent.text = cellValue;
[cell.contentView addSubview:cellContent];
return cell;



-(void)checkClicked:(UIButton *)b

checkedImg = [UIImage imageNamed:@"buttonChecked1.png"];
[check setImage:checkedImg forState:UIControlStateNormal];


通过这样做,按钮的图像会发生变化,但只有最后一个而不是单击的那个。我知道它背后的原因,但我不知道如何实现我想要的。

【问题讨论】:

【参考方案1】:

获得所需结果的结构化方式:

为表格单元格创建一个 UIView 子类(包含按钮和标签)。您实例化这些自定义视图并将它们设置为您的contentView 用于cellForRowAtIndexPath 中的每个表格单元格。

您的每个自定义视图都会监听自己的按钮是否被按下。当它被按下时,它会切换其状态并告诉主视图控制器(通过委托方法)它已被切换。主视图控制器在有问题的单元格上调用 reloadData 以使其以正确的外观重新加载。

请注意,这种方法要求您告诉每个自定义视图它在表中呈现哪个索引路径——这样它就可以通知主视图控制器的委托方法——需要这个信息来触发重新加载合适的单元格。

顺便说一句,我假设您想在用户完成编辑后查看表格中按钮的状态,而您当前的方法并没有非常明确地捕获状态内容——您必须迭代您的按钮,或将选定的项目添加到可变数组,或其他东西。

【讨论】:

【参考方案2】:

解决您的问题的简单方法是将您的 checkClicked: 方法更改为:

-(void)checkClicked:(UIButton *)b

    [b setImage:[UIImage imageNamed:@"buttonChecked1.png"] forState:UIControlStateNormal];

但是你也应该调整你的 tableView:cellForRowAtIndexPath: 方法以避免重复创建按钮并清理一些内存问题,例如:

- (UITableViewCell *)tableView:(UITableView *)_tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 

static NSString *CellIdentifier = @"Cell";    

UITableViewCell *cell = [_tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) 
    cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    UIButton *checkBtn = [UIButton buttonWithType:UIButtonTypeCustom];
    checkBtn.frame = CGRectMake(0,35,20,20);
    [checkBtn setImage:[UIImage imageNamed:@"buttonUnChecked1.png"]; forState:UIControlStateNormal];
    [checkBtn addTarget:self action:@selector(checkClicked:) forControlEvents: UIControlEventTouchUpInside];
    [cell.contentView addSubview:checkBtn];

    UILabel *cellContentLbl = [[UILabel alloc]initWithFrame:CGRectMake(40,32,500,25)];
    cellContentLbl.tag = 1;
    [cell.contentView addSubview:cellContentLbl];
    [cellContentLbl release];



//Set up the cell...
NSString *cellValue = [suggestions objectAtIndex:indexPath.row];
cellContent = (UILabel *)[cell viewWithTag:1];
cellContent.text = cellValue;
return cell;

【讨论】:

这段代码不会无法重置重复使用的单元格的状态吗?如果单击单元格的按钮,然后滚动,单击的按钮将出现在不应出现的位置。 非常感谢@theChrisKent 但是还有一个问题,如果用户再次点击它,它应该再次取消选中。为此,我将我的 checkClicked 方法更改为:-(void)checkClicked:(UIButton *)b if (!checked) [b setImage:checkedImg forState:UIControlStateNormal];检查=是; else [b setImage:unCheckedImg forState:UIControlStateNormal];但是现在,如果用户取消选中一个按钮并单击另一个按钮后,由于 Bool 值更改为 YES,它不起作用。 @Ashutosh 我的回答只解决了您眼前的问题,并没有解决您所有设计的问题。您正在尝试为多个对象/值保留单个变量,这将永远不会起作用。您不能为所有按钮或单个按钮引用使用单个 checked 值,因为这两个都将仅指向最后一个检查或创建(分别)。 @Occulus 的答案更好,因为它解决了真正的问题——你的设计。请接受他的回答(尽管请随意给我一个赞成票 :))并与他一起找出更好的解决方案。 回复:我之前关于未能重置重复使用的单元格状态的评论——请参阅 UITableViewCell 中的 prepareForReuse 方法,了解一个很好的方法。

以上是关于UITableView 每个单元格中有多个项目的主要内容,如果未能解决你的问题,请参考以下文章

uitableview 单元格中有一个横向分隔符

显示视图时 UITableView 变为非活动状态

从多节 UITableView 中的自定义静态单元格中检索标签文本

如何从自定义 UITableview 中检索有关选择单元格的数据

每个 UICollectionView 单元格中的 UITableView

在 tableview 单元格中有 MKMapview 时 UITableView reloaddata 问题