【问题标题】:iOS: On calling reloadRowsAtIndexPaths, the didEndDisplayingCell is called twiceiOS:在调用 reloadRowsAtIndexPaths 时,didEndDisplayingCell 被调用了两次
【发布时间】:2017-11-30 23:11:28
【问题描述】:

每当我打电话给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 的委托方法按以下顺序被调用:

  1. numberOfRowsInSection
  2. cellForRowAtIndexPath
  3. didEndDisplayingCell
  4. didEndDisplayingCell

为什么第二次调用这个didEndDisplayingCell 方法?请帮我解决这个问题。

【问题讨论】:

  • 看到indexPath 的值对于didEndDisplayingCell 的重复调用会很有趣...可能帮助指出原因/解决方案。
  • @DonMag,感谢您的快速回复。对didEndDisplayingCell 的重复调用的indexPath 是相同的。
  • 嗯... indexPath 有意义吗?看起来那个单元格应该被删除了吗?
  • 我传递给reloadRowAtIndexPath的indexPath,在didEndDisplayingCell的两个调用中得到的都是一样的。 AFAIK 当我们调用reloadRowAtIndexPath 时,tableView 会删除该 indexPath 处的单元格并添加新的单元格。但这不应该被调用两次。我还发现 didEndDisplayingCell cellForRowAtIndexPath 之后被调用很奇怪。
  • 如果删除对beginUpdatesendUpdates 的调用会怎样?

标签: ios objective-c uitableview firebase firebase-realtime-database


【解决方案1】:

可能的解决方法:

代替

[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])
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多