2011-05-19 76 views
6

我有一个UITableView填充了27行。我正在尝试更改所选单元格的accessoryType。我在didSelectRowAtIndexPath:委托方法中这样做。didSelectRowAtIndexPath一次选择多个行

我面临的问题是,当选择一行并更改单元格的accessoryType时,该行的第11行也会被修改。

我试过打印[indexPath row]的值,但它只显示被选中的行而不是另一个。

我很困惑这样的东西;请帮助我。

添加的代码cellForRowAtIndexPath方法

UITableViewCell *cell; 
if ([indexPath row] == 0) { 
    cell = [tableView dequeueReusableCellWithIdentifier:@"acell"]; 
} 
else { 
    cell = [tableView dequeueReusableCellWithIdentifier:@"bcell"]; 
} 

cell.selectionStyle = UITableViewCellSelectionStyleNone; 

if (cell == nil && [indexPath row] != 0) { 
    cell = [[[UITableViewCell alloc] initWithStyle: 
      UITableViewCellStyleSubtitle reuseIdentifier:@"bcell"] autorelease]; 
} 
else if(cell == nil && [indexPath row] == 0){ 
    cell = [[[UITableViewCell alloc] initWithStyle: 
      UITableViewCellStyleSubtitle reuseIdentifier:@"acell"] autorelease]; 
} 

if ([cell.contentView subviews]){ 
    for (UIView *subview in [cell.contentView subviews]) { 
     [subview removeFromSuperview]; 
    } 
} 
if ([indexPath row] == 0) { 
    cell.textLabel.text = @"Select All"; 
    cell.textLabel.font = [UIFont boldSystemFontOfSize:13.0f]; 
} 
else { 
    cell.textLabel.text = @"Some Text Here" 
    cell.detailTextLabel.text = @"Another piece of text here" 
} 
return cell; 

我做%10因为行为11行后重复,因此试图为每11行创建新的对象。

didSelectRowAtIndexPath methos代码

UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; 
if (cell.accessoryType == UITableViewCellAccessoryCheckmark) { 
    if ([indexPath row] != 0) { 
     NSIndexPath *tempIndex = [NSIndexPath indexPathForRow:0 inSection:0]; 
     UITableViewCell *tempCell = [tableView cellForRowAtIndexPath:tempIndex]; 
     tempCell.accessoryType = UITableViewCellAccessoryNone; 
    } 
    cell.accessoryType = UITableViewCellAccessoryNone; 
} 
else{ 
    cell.accessoryType = UITableViewCellAccessoryCheckmark; 
} 
if ([indexPath row] == 0) { 
    for (int i = 0; i < [dataSource count]; i++) { 
     NSIndexPath *tempIndex = [NSIndexPath indexPathForRow:i+1 inSection:0]; 
     UITableViewCell *tempCell = [tableView cellForRowAtIndexPath:tempIndex]; 
     if (cell.accessoryType == UITableViewCellAccessoryCheckmark) { 
      tempCell.accessoryType = UITableViewCellAccessoryCheckmark; 
     } 
     else{ 
      tempCell.accessoryType = UITableViewCellAccessoryNone; 
     } 
    } 
} 

请帮我多选或任何其它的方式来解决多重选择的问题。

在此先感谢!

+4

发布您的代码可能是?最有可能你正在重用cellFor错误在cellForRowAtIndexPath方法 – Vladimir 2011-05-19 11:21:29

+0

张贴您的cellforrowindex tableview代码 – 2011-05-19 11:26:20

+0

检查http://stackoverflow.com/questions/4616345/select-multiple-rows-in-uitableview/4616432例如 – Vladimir 2011-05-19 12:35:57

回答

15

下面是做这件事:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *CellIdentifier = @"Cell"; 

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
    if (cell == nil) { 
     cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];   
    } 

    [cell.textLabel setText:[NSString stringWithFormat:@"Row %d", indexPath.row]]; 

    NSIndexPath* selection = [tableView indexPathForSelectedRow]; 
    if (selection && selection.row == indexPath.row) { 
     cell.accessoryType = UITableViewCellAccessoryCheckmark; 
    } else { 
     cell.accessoryType = UITableViewCellAccessoryNone; 
    } 

    // Configure the cell. 
    return cell; 
} 

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    [tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark; 
} 

- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    [tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryNone; 
} 

记得在表视图中的每一个细胞实际上是被重新使用相同的对象。如果每次调用cellForRowAtIndexPath时都没有设置附件类型,当新的单元格滚动到屏幕上时,它们都将具有相同的附件。

多重选择

对于多重选择它更复杂一些。

你的第一个选项:未公开的API

注意,这只能在表的编辑模式。将每个单元格的编辑样式设置为未记录的UITableViewCellEditingStyleMultiSelect。一旦你这样做了,你可以通过一个UITableView的非文档成员来获取表视图的选择:indexPathsForSelectedRows。这应该返回所选单元格的数组。

你可以把这个在头部暴露的功能位:

enum { 
    UITableViewCellEditingStyleMultiSelect = 3, 
}; 

@interface UITableView (undocumented) 
- (NSArray *)indexPathsForSelectedRows; 
@end 

然后设置,像这样每个单元格的编辑风格:

- (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath { 
    return UITableViewCellEditingStyleMultiSelect; 
} 

当表处于编辑模式您会看到单元格上的多选控件。

翻阅其他未公开的API,你可以使用nm命令行实用程序是这样的:

nm /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk/System/Library/Frameworks/UIKit.framework/UIKit 

你的第二个选项:管理选择自己

有你的UITableView子类包含一个数组这表明选择了哪些单元格。然后在cellForRowAtIndexPath中,使用该数组配置单元格的外观。然后,您的didSelectRowAtIndexPath方法方法应该是这个样子:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    if ([tableView indexPathIsSelected:indexPath]) { 
     [tableView removeIndexPathFromSelection:indexPath]; 
    } else { 
     [tableView addIndexPathToSelection:indexPath]; 
    } 
    // Update the cell's appearance somewhere here 
    [tableView deselectRowAtIndexPath:indexPath animated:NO]; 
} 

这里假设你在你的UITableView子类中创建indexPathIsSelected,removeIndexPathFromSelection和addIndexPathToSelection方法。这些方法应该完全按照它们的名称暗示:添加,删除和检查数组中的索引路径。如果使用此选项,则不需要执行didDeselectRowAtIndexPath。

+0

嘿谢谢你了,如果只做单一选择,这段代码工作得很好。如果我需要实施多重选择,我应该改变什么?谢谢 – devsri 2011-05-19 12:12:53

+0

有你去。答案已更新。 :) – daxnitro 2011-05-19 13:57:56

+0

只做了一些测试,并修改了多选部分(无证API的东西)。 – daxnitro 2011-05-19 14:41:34

0

请记住,表视图中的每个单元格实际上是重复使用的同一个对象。如果您没有设置辅助型每一次的cellForRowAtIndexPath被调用时,当新细胞滚动到他们将所有的屏幕具有相同的附件“ - daxnitro

这是我被抓住了我。有我的设置,以便在我的“cellForRowAtIndexPath”函数中,我只会更改我的已检查单元格阵列中指定的那些附件,而我应该完成的工作是更新表格中所有单元格的附件。换句话说:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
//normal set up 

    //retrieve key 
    NSUserDefaults *settings = [NSUserDefaults standardUserDefaults]; 
    id obj = [settings objectForKey:@yourKey]; 

    //if the array is not populated, keep standard format for all cells 
    if (obj == nil){ 
     selectedStyles = [[NSMutableArray alloc] initWithObjects:nil]; 
     [cell setAccessoryType:UITableViewCellAccessoryNone]; //no check mark 
     [cell textLabel].textColor = [[UIColor alloc] initWithRed:0.0/255 green:0.0/255 blue:0.0/255 alpha:1.0]; //keep black color 

    } 
    //else retrieve information from the array and update the cell's accessory 
    else{ 
     //if the cell is in your array, add a checkbox 
     [cell setAccessoryType:UITableViewCellAccessoryCheckmark]; //add check box 
     [cell textLabel].textColor = [[UIColor alloc] initWithRed:50.0/255 green:79.0/255 blue:133.0/255 alpha:1.0]; //change color of text label 
     //if the cell is not in your array, then keep standard format 
     [cell setAccessoryType:UITableViewCellAccessoryNone]; //no check mark 
     [cell textLabel].textColor = [[UIColor alloc] initWithRed:0.0/255 green:0.0/255 blue:0.0/255 alpha:1.0]; //keep black color 

希望这会有所帮助!