我目前正在开发一个包含UITableView的应用程序。 UITableView包含自定义单元格。 Inside Cell我提供了一个UI按钮,用于多行选择。在tableView当前我有30行,它工作正常但是,当我点击第一行中的按钮时,第6,11,16,21,26行中的按钮也会被点击,如果点击后面的第二行下一行被点击(即7日,12日等等......)。
代码如下:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
//
// Create the cell.
//
cell =
[[[UITableViewCell alloc]
initWithFrame:CGRectZero
reuseIdentifier:CellIdentifier]
autorelease];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
indicatorImage = [UIImage imageNamed:@"NotSelected.png"];
indicatorHighImage = [UIImage imageNamed:@"IsSelected.png"];
selectbtn = [UIButton buttonWithType:UIButtonTypeCustom];
selectbtn.frame = CGRectMake(30,122,20,20);
[selectbtn setImage:indicatorImage forState:UIControlStateNormal];
selectbtn.tag = rowCount++;
[cell addSubview:selectbtn];
[selectbtn addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
}
return cell;
}
-(IBAction)buttonClicked:(UIButton *)button
{
if([button isSelected])
{
[button setImage:indicatorImage forState:UIControlStateNormal];
[button setSelected:NO];
}
else
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Custom Button Pressed"
message:[NSString stringWithFormat: @"You pressed the custom button on cell #%i", button.tag]//pathToCell.row + 1]
delegate:self cancelButtonTitle:@"Great"
otherButtonTitles:nil];
[alertView show];
[alertView release];
[button setImage:indicatorHighImage forState:UIControlStateNormal];
[button setSelected:YES];
}
return;
}
答案 0 :(得分:2)
好的,首先,您正在错误地设置按钮图像。要设置选定和未选择的按钮状态,每次按下按钮时都不会更改图像,只需在创建按钮时执行此操作:
[button setImage:indicatorImage forState:UIControlStateNormal];
[button setImage:indicatorHighImage forState:UIControlStateSelected];
注意forState参数 - 这允许您指定图像的显示状态,这样,当您设置其selected属性时,按钮将自动显示另一个图像。在buttonClicked方法中,您现在可以说:
button.selected = !button.selected; // toggle selection state
现在第二个问题是选择一个按钮选择其他按钮是由于表格单元格在表格中的回收方式。如果在一个单元格上设置一些属性(例如,选择一个按钮),该单元格将在表格中多次重复使用,并且它将保持该状态。一个包含100行的表格不包含100个单元格,它可能包含10个单元格,当您滚动它时,只需不断重复使用这些10个单元格。
因此,您无法在表格单元格中存储状态信息。您需要使用一组模型对象来支持表,并且每次调用cellForRowAtIndexPath方法时,您都需要使用等效索引从数组中的对象重置单元属性。
此外,您在cellForRowAtIndexPath方法的if (cell == nil) { ... }
子句中执行的一些操作需要移动到if语句之外,否则它们将仅在第一次创建单元格时设置并赢得'重新使用时再次设置。
所以你的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;
selectbtn = [UIButton buttonWithType:UIButtonTypeCustom];
[selectbtn setImage:[UIImage imageNamed:@"NotSelected.png"] forState:UIControlStateNormal];
[selectbtn setImage:[UIImage imageNamed:@"IsSelected.png"] forState:UIControlStateSelected];
selectbtn.frame = CGRectMake(30,122,20,20);
[cell addSubview:selectbtn];
[selectbtn addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
}
//get a model object from the array
MyModelObject *object = [myBackingArray objectAtIndex:indexPath.row];
//get the button and set its properties
UIButton *button = [cell.subviews lastObject];
button.tag = rowCountindexPath.row;
button.selected = object.mySelectedStateProperty;
return cell;
}
请注意,MyModelObject,myBackingArray和object.mySelectedStateProperty是您将作为单元格数据模型创建的新类的占位符,以及存储在视图控制器中的这些对象的数组,以充当存储单元格状态的永久位置