reloadRowsAtIndexPaths 的副作用?

Posted

技术标签:

【中文标题】reloadRowsAtIndexPaths 的副作用?【英文标题】:reloadRowsAtIndexPaths side effects? 【发布时间】:2015-05-20 12:30:33 【问题描述】:

我有一个 UITableView 充满了 UITableViewCell 包含一个复选标记。

当我点击一个单元格时,如果它被标记,它将变为未标记,反之亦然。

到目前为止一切顺利。现在我想在每次单击任何其他单元格时更新第一个单元格(假设第一个单元格是特殊的)。我修改了 didSelectRowAtIndexPath 的代码(见下文),它可以正常工作,只是在单击的单元格上出现以下不良行为:

如您所见,单元格顶部的白线已消失...

这是我的代码(我猜)关键功能的样子:

- (UITableViewCell *)tableView:(UITableView *)aTableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
    UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];
    cell.selectionStyle = UITableViewCellSelectionStyleNone;
    cell.backgroundColor = [UIColor darkGrayColor];
    cell.textLabel.textColor = [UIColor whiteColor];
    cell.textLabel.text = [myLabels objectAtIndex:indexPath.row];
    bool isChecked = false;
    if ([currentValues[indexPath.row] boolValue]) 
        isChecked = true;
    
    cell.accessoryType =  isChecked ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;
    return cell;



- (void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
    UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
    bool isChecked = false;
    if ([currentValues[indexPath.row] boolValue]) 
        isChecked = false;
        currentValues[indexPath.row] = [NSInteger numberWithBool:false];

        // below is the part of code that causes trouble

        [self.tableView beginUpdates];
        NSIndexPath* indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
        [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
        [self.tableView endUpdates];

        // end of problematic code
    

    else 
        isChecked = true;
        currentValues[indexPath.row] = [NSInteger numberWithBool:true];
        // similarly...
        [self.tableView beginUpdates];
        NSIndexPath* indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
        [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
        [self.tableView endUpdates];
     
    cell.accessoryType = isChecked ? UITableViewCellAccessoryCheckmark :UITableViewCellAccessoryNone;

NB如果我重新加载整个表,那么我就没有这个问题。但我觉得了解那里发生的事情对我来说可能是值得的。

NB2我尝试了调用和不调用 [self.tableView beginUpdates] 和 [self.tableView endUpdates],但似乎没有什么不同。

【问题讨论】:

【参考方案1】:

didSelectRowAtIndexPath 会做一些小的改变,比如,

- (void)tableView:(UITableView *)aTableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
    UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
    bool isChecked = false;
    if ([currentValues[indexPath.row] boolValue]) 
        isChecked = false;
        currentValues[indexPath.row] = [NSInteger numberWithBool:false];

        // below is the part of code that causes trouble
        [self.tableView deselectRowAtIndexPath:indexPath animated:NO]; 
        //MYCHANGES
        [self.tableView beginUpdates];
        NSIndexPath* indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
        [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
        [self.tableView endUpdates];

        // end of problematic code
    

    else 
        isChecked = true;
        currentValues[indexPath.row] = [NSInteger numberWithBool:true];
        // similarly...
        [self.tableView deselectRowAtIndexPath:indexPath animated:NO]; 
        //MYCHANGES
        [self.tableView beginUpdates];
        NSIndexPath* indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
        [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
        [self.tableView endUpdates];
     
    cell.accessoryType = isChecked ? UITableViewCellAccessoryCheckmark :UITableViewCellAccessoryNone;

【讨论】:

很棒的答案,非常感谢!知道不取消选择单元格时会发生什么吗?为什么这会导致白线消失? 你可以说,这是来自Apple的错误,我没有太多想法,但只要选择行/单元格,如果你执行重新加载单元,它会删除分隔符,直到你重新加载tableview,这不是每次都合适的解决方案。

以上是关于reloadRowsAtIndexPaths 的副作用?的主要内容,如果未能解决你的问题,请参考以下文章

如何覆盖 reloadRowsAtIndexPath?

reloadRowsAtIndexPaths 崩溃;重新加载数据工作

reloadRowsAtIndexPaths 时保持偏移

UITableView reloadRowsAtIndexPaths 图形故障

reloadRowsAtIndexPaths 使用 JSON imageUrls 崩溃

reloadRowsAtIndexPaths 的副作用?