每当我打电话给reloadRowsAtIndexPaths; didEndDisplayingCell方法被调用两次。为什么会这样呢?

我已经实现了UITableViewDelegate和UITableViewDataSource的以下委托方法:

  • - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
  • - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
  • - (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath*)indexPath

  • 我实现didEndDisplayingCell的原因是,我想分离Firebase侦听器。

    这是我在 didEndDisplayingCell中实现的功能
    - (void)tableView:(UITableView *)tableView didEndDisplayingCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath*)indexPath{
    // detach the listener for the cell at path index indexPath
    
      CustomCell* customCell = (CustomCell*)(cell);
      [customCell detachListener];
    }
    

    每当单元格侦听更新的数据时,它都会在ViewController中触发一个方法,该方法会重新加载tableViewCell。这是我实现该方法的方式:
    -(void)refreshCellWithIndexPath:(NSIndexPath*) indexPath andData:(CustomData*)data{
    
      [self.dataArray replaceObjectAtIndex:indexPath.row withObject:data];
    
      [self.tableView beginUpdates];
      [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
      [self.tableView endUpdates];
    }
    

    执行此方法时,将按以下顺序调用UITableView委托方法:
  • numberOfRowsInSection
  • cellForRowAtIndexPath
  • didEndDisplayingCell
  • didEndDisplayingCell

  • 为什么第二次调用此didEndDisplayingCell方法? ,请帮助我。

    最佳答案

    可能的解决方法:

    代替

    [self.tableView beginUpdates];
    [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
    [self.tableView endUpdates];
    

    使用(快速):
    reloadCounter += 1
    CATransaction.begin()
    tableView.beginUpdates()
    CATransaction.setCompletionBlock {
        self.reloadCounter -= 1
    }
    tableView.reloadRows(at: [IndexPath(row: row, section: 0)], with: .none)
    tableView.endUpdates()
    CATransaction.commit()
    

    reloadCounter是一个ivar。

    在didEndDisplaying中:
    func tableView(_ tableView: UITableView, didEndDisplaying cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        if (reloadCounter == 0) {
            self.output.didEndDisplaying(viewModel: dataProvider.items[indexPath.row])
        }
    }
    

    关于ios - iOS:在调用reloadRowsAtIndexPaths时,didEndDisplayingCell被调用了两次,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44788055/

    10-10 20:02