【问题标题】:UITableView with multiple items in each cellUITableView 每个单元格中有多个项目
【发布时间】: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];

}

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

【问题讨论】:

    标签: iphone objective-c ios uitableview uibutton


    【解决方案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 方法,了解一个很好的方法。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-08
      相关资源
      最近更新 更多