UITableView 中 cell.accessoryType 的问题

Posted

技术标签:

【中文标题】UITableView 中 cell.accessoryType 的问题【英文标题】:problem in cell.accessoryType in UITableView 【发布时间】:2011-04-28 14:45:20 【问题描述】:

在我的应用程序中,如果用户按下 UITableView 中的任何单元格,则单元格的附件类型将设置为复选标记,如下所示

-(void)Check:(UITableView *)tableView Mark:(NSIndexPath *)indexPath  
  
[self.tableView cellForRowAtIndexPath:indexPath].accessoryType = UITableViewCellAccessoryCheckmark;  
     buttonCount++;  
    [selectedCellArray addObject:indexPath];  
 

如果用户按下相同的单元格,则取消选中将发生如下情况

-(void)UnCheck:(UITableView *)tableView Mark:(NSIndexPath *)indexPath  
  
[self.tableView cellForRowAtIndexPath:indexPath].accessoryType =   UITableViewCellAccessoryNone;  
    buttonCount--;    
     if (buttonCount == 0)     

        [selectedCellArray removeAllObjects];  
      
    

我叫这个

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
  
if([tableView cellForRowAtIndexPath:indexPath].accessoryType == UITableViewCellAccessoryCheckmark)
      
        [self UnCheck:tableView Mark:indexPath];  
      
else  
      
        [self Check:tableView Mark:indexPath];

    

问题是当我按下第一个单元格时,它会调用 Check 方法并将单元格标记为,但是当我向下滚动时,我发现还有 2-3 个 cheked 单元格...即使我没有选择那些单元格...我没有知道为什么以及如何自动检查... 我希望有人知道问题出在哪里 非常感谢

【问题讨论】:

【参考方案1】:

因为单元格将被表格视图重用。还要在 tableView:cellForRowAtIndexPath: 方法中设置复选标记/附件类型。

【讨论】:

完美,非常感谢,但现在如果我选择 4-5 个单元格并向下或向上滚动,我看不到复选标记 您必须根据 indexPath 是否在 selectedCellArray 中来设置类型(在 cellForRow 中...)。您必须了解,在 cellForRow... 中,使用 dequeCell... 您有时会创建一个全新的单元格,有时会重用现有的单元格。因此,每次返回单元时,都需要重新配置单元(附件类型设置等)。尝试跳过 dequeCell... 看看效果。【参考方案2】:

是的。我经常看到这种情况发生。

管理 UITableViewCell 状态的正确模式不是直接操作 TableViewCell 来更新 UI,而是始终从 cellForRowAtIndexPath(或 tableView:willDisplayCell:forRowAtIndexPath:) 设置、绘制和创建正确的状态

意思是,如果用户单击单元格并且您需要更新该单元格的 UI,则将该单元格的新状态存储在数组或字典中(我发现以 NSIndexPath 为键的 NSMutableDictionary 效果很好)。

然后调用 reloadRowsAtIndexPaths:withRowAnimation: 或只是 [tableView reloadData] 以便 cellForRowAtIndexPath 读取该数组或字典并正确绘制单元格。

否则,cellForRowAtIndexPath 将不断覆盖您的更改并使用状态不正确的回收单元。

此规则的一个例外是,如果您希望两个状态之间有一个漂亮的动画...如果是这种情况,请保存您的新状态,在单元格上执行您的动画,然后在动画完成时,调用相同的 reloadRowsAtIndexPaths:withRowAnimation 或 reloadData 以便单元格以新状态重绘。

【讨论】:

我应该调用 reloadRowsAtIndexPaths:withRowAnimation: in tableView:cellForRowAtIndexPath:mehtod no.. 这会导致堆栈溢出。 reloadRowsAtIndexPaths 导致 tableView 调用 cellForRowAtIndexPath

以上是关于UITableView 中 cell.accessoryType 的问题的主要内容,如果未能解决你的问题,请参考以下文章

如何在没有数组的 UITableView 中显示 UITableView Cell?

如果目标 c 的 uitableview 中没有新行,如何停止滚动 uitableview?

如果 UITableView 在 UIScrollView 中,则无法在 UITableView 上执行滑动删除

水平 UITableView 中的垂直 UITableView

在 Scrollview 中适配 UITableview

保持 uisearchbar 在 uitableview 中始终可见