UITableView,在选择时更改配件时出现问题

时间:2009-06-10 07:39:23

标签: iphone objective-c uitableview

我正在使用UITableView来选择一个(很多)项目。与选择铃声时的UI类似,我想要检查所选项目,而不是其他项目。我想在触摸时选择单元格,然后将其设置为正常颜色(再次像铃声选择UI一样)。

UIViewController子类是我的表的委托和数据源(不是UITableViewController,因为我还有一个工具栏)。

我正在设置cellForRowAtIndexPath:中的单元格的accessoryType,并在didSelectRowAtIndexPath:中选择单元格时更新我的​​模型。我可以想到将所选单元格设置为复选标记(并清除前一个单元格)的唯一方法是在didSelectRowAtIndexPath:中调用[tableView reloadData]。但是,当我这样做时,单元格取消选择的动画很奇怪(单元格的标签应该出现一个白框)。如果我不调用reloadData,当然,accessoryType不会改变,因此不会出现复选标记。

我想我可以关闭动画,但这似乎很蹩脚。我也玩弄了改变didSelectRowAtIndexPath:中的细胞,但这是一个很大的痛苦。

有什么想法吗?缩写代码如下......

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell* aCell = [tableView dequeueReusableCellWithIdentifier:kImageCell];
    if( aCell == nil ) {
        aCell = [[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:kImageCell];
    }

    aCell.text = [imageNames objectAtIndex:[indexPath row]];
    if( [indexPath row] == selectedImage ) {
        aCell.accessoryType = UITableViewCellAccessoryCheckmark;
    } else {
        aCell.accessoryType = UITableViewCellAccessoryNone;
    }
    return aCell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    [tableView deselectRowAtIndexPath:indexPath animated:YES];
    selectedImage = [indexPath row]
    [tableView reloadData];
}

7 个答案:

答案 0 :(得分:8)

我像他在编辑中建议的那样解决了这个问题。我的代码示例确保只检查了一行,但我确信如果不是您需要的话,您可以调整它。

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

int newRow = [indexPath row];
int oldRow = [lastIndexPath row];

if (newRow != oldRow)
{
    UITableViewCell *newCell = [tableView cellForRowAtIndexPath:
                                indexPath];
    newCell.accessoryType = UITableViewCellAccessoryCheckmark;

    UITableViewCell *oldCell = [tableView cellForRowAtIndexPath:
                                lastIndexPath];
    oldCell.accessoryType = UITableViewCellAccessoryNone;

    lastIndexPath = indexPath;
}

[tableView deselectRowAtIndexPath:indexPath animated:YES];
}

答案 1 :(得分:4)

我遇到了同样的问题但从未解决过。

最后这对我来说没有意义,因为我必须监听模型中的更改(如果连接丢失,选择可能会随用户的控制而改变)所以我只是更改了模型并让通知重新加载数据,但它看起来并不太漂亮(它就像一个非动画的取消选择,但是一个循环迭代迟到了!)

我怀疑唯一的方法是,正如你所建议的那样,保留对单元格本身的引用缓存。如果你编写一个UITableViewCell子类来封装逻辑,那么这应该不会太乱,重写-prepareForReuse。

尽管如此,并不漂亮,如果Apple的铃声人员不得不这样做,他们应该更难以修复UITableView团队!

编辑:

嗯,你知道什么?!毕竟这真的很容易。 - [UITableView cellForRowAtIndexPath]将为您提供实际的单元格(如果它们在屏幕外,则为nil),您只需更改accessoryType。

答案 2 :(得分:2)

我有一种更清洁的方式。

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];

    if (cell.accessoryType == UITableViewCellAccessoryNone) {
        cell.accessoryType = UITableViewCellAccessoryCheckmark;

    } else {
        cell.accessoryType = UITableViewCellAccessoryNone;
    }
}

答案 3 :(得分:2)

我正在使用这个简单而漂亮的工作机制和reloadRowsAtIndexPaths。

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    NSArray *rowsArray = [NSArray arrayWithObjects:indexPath, selectedIndexPath, nil];
    self.selectedIndexPath = indexPath;

    [tableView reloadRowsAtIndexPaths:rowsArray withRowAnimation:UITableViewRowAnimationNone];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    .... skipped usual code .....

    if ([selectedIndexPath compare:indexPath] == NSOrderedSame) {
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
    } else {
        cell.accessoryType = UITableViewCellAccessoryNone;
    }
    return cell;
}

答案 4 :(得分:1)

这将按预期工作......

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {


int newRow = [indexPath row];
int oldRow = [lastIndexPath row];


if (newRow == oldRow){
    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];

    if (cell.accessoryType == UITableViewCellAccessoryNone) {
        cell.accessoryType = UITableViewCellAccessoryCheckmark;

    } else {
        cell.accessoryType = UITableViewCellAccessoryNone;
    }

     lastIndexPath = indexPath;
}


if (newRow != oldRow)
{
    UITableViewCell *newCell = [tableView cellForRowAtIndexPath:indexPath];
    newCell.accessoryType = UITableViewCellAccessoryCheckmark;

    UITableViewCell *oldCell = [tableView cellForRowAtIndexPath:lastIndexPath];
    oldCell.accessoryType = UITableViewCellAccessoryNone;

    lastIndexPath = indexPath;
}


[tableView deselectRowAtIndexPath:indexPath animated:YES];

}

答案 5 :(得分:0)

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

答案 6 :(得分:0)

在SOF的另一个帖子中找到答案,就像一个魅力:iPhone :UITableView CellAccessory Checkmark