代码之家  ›  专栏  ›  技术社区  ›  coder

iOS 7开始更新结束更新不一致

  •  8
  • coder  · 技术社区  · 11 年前

    编辑 : 这个答案的解决方案与iOS7有关,有时会返回 NSIndexPath 其他时间返回 NSMutableIndexPath 。这个问题与 begin/endUpdates ,但希望这个解决方案能帮助其他一些人。


    全部-我在iOS 7上运行我的应用程序,遇到了问题 beginUpdates endUpdates 方法 UITableView .

    我有一个表格视图,当被触摸时需要更改单元格的高度。以下是我的代码:

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    
            // If our cell is selected, return double height
            if([self cellIsSelected:indexPath]) {
                return 117;
            }
    
            // Cell isn't selected so return single height
            return 58;
    
    }
    
    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
    
            ChecklistItemCell *cell = (ChecklistItemCell *)[self.tableview cellForRowAtIndexPath:indexPath];
            [cell.decreaseButton setHidden:NO];
            [cell.increaseButton setHidden:NO];
    
            // Toggle 'selected' state
            BOOL isSelected = ![self cellIsSelected:indexPath];
    
            DLog(@"%@", selectedIndexes);
    
            DLog(@"is selected: %@", isSelected ? @"yes":@"no");
            // Store cell 'selected' state keyed on indexPath
            NSNumber *selectedIndex = @(isSelected);
            selectedIndexes[indexPath] = selectedIndex;
    
            [tableView beginUpdates];
            [tableView endUpdates];
    
    }
    

    这个 开始更新 结束更新 这些方法的效果相当不一致。这个 didSelectRowAtIndexPath 方法在每次触摸时都会被正确调用(一开始我以为UI被阻止了) selectedIndexes 正在正确存储交替值。问题是,有时我触摸一个表格单元格,所有的方法都被正确调用,但单元格的高度不会改变。有人知道发生了什么吗?

    2 回复  |  直到 11 年前
        1
  •  21
  •   Timothy Moose    11 年前

    iOS7中的行为发生了变化,其中索引路径有时是 NSIndexPath 和其他时间 UIMutableIndexPath 。问题是 isEqual 在这两个班之间总是会回来 NO 。因此,您无法可靠地将索引路径用作字典键或在依赖 等于 .

    我可以想出几个可行的解决方案:

    1. 编写一个始终返回的实例的方法 NSIndexPath(NS索引路径) 并使用它生成密钥:

      - (NSIndexPath *)keyForIndexPath:(NSIndexPath *)indexPath
      {
          if ([indexPath class] == [NSIndexPath class]) {
              return indexPath;
          }
          return [NSIndexPath indexPathForRow:indexPath.row inSection:indexPath.section];
      }
      
    2. 通过数据而不是索引路径来标识行。例如,如果您的数据模型是 NSString ,将该字符串用作 selectedIndexes 地图如果您的数据模型是 NSManagedObjects ,使用 objectID

    我在代码中成功地使用了这两种解决方案。

    编辑 基于@rob返回建议的修改解决方案(1) NSIndexPaths 而不是 NSStrings .

        2
  •  0
  •   NRitH    11 年前

    endUpdates 之后不应该立即调用 beginUpdates 后者的文档指出,“开始一系列方法调用,插入、删除或选择接收器的行和部分。”这表明应该在 willSelectRowAtIndexPath: 结束更新 应该调用 didSelectRowAtIndexPath .