Ios UITableView内容大小何时随行插入/删除动画更新

Ios UITableView内容大小何时随行插入/删除动画更新,ios,cocoa-touch,uitableview,Ios,Cocoa Touch,Uitableview,我很好奇在执行插入/删除动画调用后,UITableView的内容大小何时更新。我认为这就像大多数[UIView动画…]块一样,即使动画尚未完成,帧大小/内容大小也会立即更新,但似乎不是这样。有什么想法吗?在向学员询问身高后,内容大小将发生变化: - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath; - (CGFloat)tableView:(UITableVi

我很好奇在执行插入/删除动画调用后,UITableView的内容大小何时更新。我认为这就像大多数[UIView动画…]块一样,即使动画尚未完成,帧大小/内容大小也会立即更新,但似乎不是这样。有什么想法吗?

在向学员询问身高后,内容大小将发生变化:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section;
- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section;

不幸的是,在从UITableView添加/删除行时,我也未能找到一种更新contentSize的好方法,但我确实找到了一种方法来计算如果您知道要添加/删除的单元格的索引路径会是什么

使用修改行的索引路径,可以使用tableView:heightForRowAtIndexPath:方法计算相应单元格的高度,并将其添加到表视图的当前内容大小高度。以下是仅添加一行的示例:

[self.tableView insertRowsAtIndexPaths:@[indexPathOfNewRow] withRowAnimation:UITableViewRowAnimationAutomatic];
CGFloat newCellHeight = [self tableView:self.tableView heightForRowAtIndexPath:indexPathOfNewRow];
CGFloat newContentSizeHeight = self.tableView.contentSize.height + newCellHeight

看起来
sizehatfits()
可以显示待处理的新
contentSize
的高度。然后,您可以为滚动动画指定挂起的大小以使其尽早解析

比如说:

extension UIScrollView {

    var pendingContentSize: CGSize {
        var tallSize = contentSize
        tallSize.height = .greatestFiniteMagnitude
        return sizeThatFits(tallSize)
    }

    func scrollToBottom(animated: Bool) {
        contentSize = pendingContentSize
        let contentRect = CGRect(origin: .zero, size: contentSize)
        let (bottomSlice, _) = contentRect.divided(atDistance: 1, from: .maxYEdge)
        guard !bottomSlice.isEmpty else { return }
        scrollRectToVisible(bottomSlice, animated: animated)
    }

}
tableView.insertRows(at: [newIndexPath], with: .none)
tableView.scrollToBottom(animated: true)
我能够编写如下视图控制器代码:

extension UIScrollView {

    var pendingContentSize: CGSize {
        var tallSize = contentSize
        tallSize.height = .greatestFiniteMagnitude
        return sizeThatFits(tallSize)
    }

    func scrollToBottom(animated: Bool) {
        contentSize = pendingContentSize
        let contentRect = CGRect(origin: .zero, size: contentSize)
        let (bottomSlice, _) = contentRect.divided(atDistance: 1, from: .maxYEdge)
        guard !bottomSlice.isEmpty else { return }
        scrollRectToVisible(bottomSlice, animated: animated)
    }

}
tableView.insertRows(at: [newIndexPath], with: .none)
tableView.scrollToBottom(animated: true)

并让表格一直滚动到底(使用新的内容大小),而不是向下滚动到倒数第二行(使用旧的内容大小)。

感谢您的回复。是否有任何方式可以通知我,或者有任何类型的委托方法可以告诉我内容大小已更改?这似乎是在动画完成后发生的,但我希望在此之前获得新的内容大小,这样我就可以根据实际情况对表格周围的内容进行动画制作。我尝试了这一点,并在调用tableview:heightForRowAtIndexPath:method前后放置了日志语句,但没有看到内容大小得到更新。然而,这确实帮助我找到了一个计算内容大小的解决方案。我将把解决方案作为单独的答案发布。你解决了这个问题吗?我遇到了同样的问题。插入/删除行,然后希望更新tableView.contentSize,但这似乎是异步的。