草庐IT

swift - UITableViewController : Scrolling to bottom with dynamic row height starts animation at wrong position

coder 2023-07-17 原文

根据找到的 Ray Wenderlich 指南 here,我有一个 TableView 已正确配置为具有动态行高:

我将约束设置为从单元格的顶部到底部有一条清晰的约束线。我还设置了内容拥抱和内容压缩阻力优先级以及估计的行高。

这是我用来设置表格 View 的代码:

func configureTableView() {
    // its called on viewDidLoad()
    tableView.rowHeight = UITableViewAutomaticDimension
    tableView.estimatedRowHeight = 100.0
}

override func viewDidLoad() {
    super.viewDidLoad()

    configureTableView()

    for i in 1...20 {
        messages.append([
            "title": "foo \(i)",
            "message": "bla \(i)\nbla\nbla"
        ])
    }

    // this is because the actual row heights are not available until the next layout cycle or something like that
    dispatch_async(dispatch_get_main_queue(), {self.scrollToBottom(false)})
}

func scrollToBottom(animated:Bool) {
    let indexPath = NSIndexPath(forRow: self.messages.count-1, inSection: 0)

    self.tableView.scrollToRowAtIndexPath(indexPath, atScrollPosition: UITableViewScrollPosition.Bottom, animated: animated)
}

这就是我添加新行的方式:

@IBAction func addMore(sender:UIBarButtonItem) {
    let message = [
        "title": "haiooo",
        "message": "silver"]

    messages.append(message)

    let indexPath = NSIndexPath(forRow: messages.count-1, inSection: 0)

    tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Bottom)

    scrollToBottom(true)
}

默认行的设置很好。它按预期将行和滚动条添加到底部。

但是当我之后添加新行时,滚动似乎从最后一个单元格上方开始。当我添加更多单元格时,偏移量似乎会增加。

这是一个显示它发生的 gif:Imgur

它肯定与滚动动画(而不是 insertRow 动画)有关,因为当动画关闭时它会正确滚动。

更改 estimatedRowHeight 会影响滚动偏移量,但我找不到修复它的值。

我还尝试使用 dispatch_async 延迟滚动,但它没有改变任何东西。

你们有什么想法吗?

最佳答案

哇,这是一个有趣的挑战。感谢您发布测试项目。

因此,在添加新行后,表格 View 认为它滚动到的位置似乎有些不对劲。在我看来是 UIKit 中的错误。因此,为了解决这个问题,我添加了一些代码以在应用动画之前“重置”表格 View 。

这是我最终得到的结果:

@IBAction func addMore(sender:UIBarButtonItem) {
    let message = [
        "title": "haiooo",
        "message": "silver"]
    messages.append(message)

    tableView.reloadData()

    // To get the animation working as expected, we need to 'reset' the table
    // view's current offset. Otherwise it gets confused when it starts the animation.
    let oldLastCellIndexPath = NSIndexPath(forRow: messages.count-2, inSection: 0)
    self.tableView.scrollToRowAtIndexPath(oldLastCellIndexPath, atScrollPosition: .Bottom, animated: false)

    // Animate on the next pass through the runloop.
    dispatch_async(dispatch_get_main_queue(), {
        self.scrollToBottom(true)
    })
}

我无法让它与 insertRowsAtIndexPaths(_:withRowAnimation:) 一起工作,但 reloadData() 工作正常。然后在动画到新的最后一行之前再次需要相同的延迟。

关于swift - UITableViewController : Scrolling to bottom with dynamic row height starts animation at wrong position,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35248912/

有关swift - UITableViewController : Scrolling to bottom with dynamic row height starts animation at wrong position的更多相关文章

随机推荐