如何观察细胞附件类型是否检查UITableViewCellAccessoryCheckmark?

时间:2012-08-25 10:08:37

标签: iphone objective-c ios uitableview

我如何观察细胞附件类型UITableViewCellAccessoryCheckmark是否已被检查?

在我的应用中,我在UITableView中添加了UIAlertView。我也用过

cell.accessoryType = UITableViewCellAccessoryCheckmark;

在我的tableView中,我有9行。当用户点击第一行时,除第二行外,所有行都将被检查。用户可以根据需要检查任何行/行。当用户点击第二行时,只检查第二行。

提前致谢:)

4 个答案:

答案 0 :(得分:1)

由于项目数量很小,您可以使用单个整数和位掩码对已检查/未检查状态进行建模。使用数字的低9位表示已选中/未选中状态:

// Add an instance variable to your view controller
// Initialize to 0 in the designated initializer
NSUInteger checkedFlags;

- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *res = ... // Dequeue the cell and so on

    res.accessoryType = (checkedFlags & (1 << indexPath.row))
    ?    UITableViewCellAccessoryCheckmark
    :    UITableViewCellAccessoryNone;

    ... // The rest of the method
}

以下是检查/取消选中/切换单个行的方法:在您的代理人的tableView:willSelectRowAtIndexPath:中,执行以下操作之一:

checkedFlags |= (1 << indexPath.row); // Check
checkedFlags &= ~(1 << indexPath.row); // Uncheck
checkedFlags ^= (1 << indexPath.row); // Toggle

如果要一次检查/取消选中多行,请使用由二进制形式检查/取消选中的行对应的位组成的数字进行掩码。例如,位为2..8的数字为{{ 1}}。

0x01FC0

操作checkedFlags |= 0x1FC0; // Check rows #3 through #9 变量后,不要忘记致电reloadData

答案 1 :(得分:1)

虽然@dasblinkenlight的答案肯定更优雅,但对你来说可能太先进了。

本质上是跟踪哪些单元格被检查以及哪些单元格未被选中。每当有什么变化时,重新加载表视图以更新复选标记。

您需要创建自己的变量来跟踪此情况。位图非常经济和优雅,但可能难以理解并且不能扩展到大量行。或者,您可以使用数组。

NSMutableArray *checkedArray = [NSMutableArray arrayWithObjects:
                   [NSNumber numberWithBool:YES],
                   [NSNumber numberWithBool:NO],
                   [NSNumber numberWithBool:NO],
                   [NSNumber numberWithBool:NO],
                   [NSNumber numberWithBool:NO],
                   [NSNumber numberWithBool:NO],
                   [NSNumber numberWithBool:NO],
                   [NSNumber numberWithBool:NO],
                   [NSNumber numberWithBool:NO],
                   nil];

要更改给定索引路径的行:

[checkedArray replaceObjectAtIndex:indexPath.row 
                        withObject:[NSNumber numberWithBool:YES]]; //add

[checkedArray replaceObjectAtIndex:indexPath.row 
                        withObject:[NSNumber numberWithBool:NO]]; //remove

cellForRowAtIndexPath中,请确保明确设置附件:

if ([[checkedArray objectAtIndex:indexPath.row] boolValue]) {
    cell.accessoryType = UITableViewCellAccessoryTypeCheckmark;
} 
else {
    cell.accessoryType = UITableViewCellAccessoryTypeNone;
}

答案 2 :(得分:0)

if ([[tableView cellForRowAtIndexPath:indexPath ] accessoryType] == UITableViewCellAccessoryCheckmark){

}
else{ 

}

答案 3 :(得分:0)

我知道这已经得到了解答,但是我已经很幸运地维护了一个NSMutableIndexSet实例,并为已检查/未检查的行添加/删除了索引。

关键方法:

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

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

    NSInteger index = indexPath.row;
    cell.accessoryType = ([self.selectedRowsIndexSet containsIndex:index]) ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;
    cell.textLabel.text = [NSString stringWithFormat:@"Row %d",index];

    return cell;
}

这是相当直接的 - 检查索引是否被选中并相应地设置附件。

对于多选(即可以选择任何调用)tableView:didSelectRowAtIndexPath:的实现如下所示:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSInteger index = indexPath.row;
    if ([self.selectedRowsIndexSet containsIndex:index])
        [self.selectedRowsIndexSet removeIndex:index];
    else
        [self.selectedRowsIndexSet addIndex:index];

    [tableView reloadRowsAtIndexPaths:@[ indexPath ] withRowAnimation:UITableViewRowAnimationAutomatic];
}

只需添加索引,重新加载表。对于单个选择它也很快

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSInteger oldIndex = [self.selectedRowsIndexSet firstIndex];
    NSInteger newIndex = indexPath.row;
    [self.selectedRowsIndexSet removeIndex:oldIndex];
    [self.selectedRowsIndexSet addIndex:newIndex];
    [tableView reloadRowsAtIndexPaths:@[ indexPath, [NSIndexPath indexPathForRow:oldIndex inSection:0] ]
                     withRowAnimation:UITableViewRowAnimationAutomatic];
}

当然可以通过更多部分变得更复杂,某些部分中的选择是否依赖于其他部分中的选择,等等。我一直在为前者使用每个部分的索引集数组,然后使用涉及后者的基础数据模型的各种复杂逻辑。但是将基本表视图交互保持在仅查询索引集的级别有助于保持这些方法非常简短和可读。