【问题标题】:Cells disappearing during animation of UITableViewUITableView 动画期间单元格消失
【发布时间】:2017-06-15 10:38:21
【问题描述】:

我的UIViewController 中有一个普通的UITableView,被限制为全屏。这个 tableView 有一个自定义的交互式tableHeaderView。 tableHeaderView 的大小是动态的,并且会自行扩展。 headerView 有一个 textField,它会根据 textField 是否有焦点来改变自己的大小。

问题是屏幕底部的单元格在更改 tableHeaderView 的大小时并不总是正确动画。 我在动画块内的layoutIfNeeded() 之后调用tableView.beginUpdates()tableView.endUpdates()。必须这样做,否则单元格根本不会遵循动态大小。

我制作了这个 gif。在动画期间专门查看底部单元格。我已经大大放慢了动画的速度,所以很容易看出问题。

推测:在我看来,tableView 在动画开始时就调用cellForRow:indexPath:,并以某种方式找出整个 tableView 在动画之后将处于什么状态,并删除不必要的单元格,即使动画尚未完成。 同样,折叠标题时:最底部的单元格的动画方式与已加载的单元格不同。它们使用不同的动画进行动画处理..

为什么会这样?这可以预防吗?

编辑:动画代码

self.navigationController?.setNavigationBarHidden(isEditing, animated: true)

var frame = tableHeaderView.frame
frame.size.height = tableHeaderView.headerHeight(forEditing: isEditing)

UIView.animate(withDuration: 0.3, animations: {

    if isEditing{
        let point = CGPoint(x: 0, y: -self.topLayoutGuide.length)
        self.tableView.setContentOffset(point, animated: false)
    }    

    tableHeaderView.frame = frame
    tableHeaderView.layoutIfNeeded()
    self.view.layoutIfNeeded()
    self.tableView.beginUpdates()
    self.tableView.endUpdates()
}) { [weak self](completed:Bool) in
    //Do stuff
}

【问题讨论】:

  • 你能显示代码吗?
  • 在故事板中-选择场景->显示属性检查器->在顶栏下,在顶栏下取消勾选。
  • @Sti : 使用应该共享一些代码。
  • @jalone 没有太多可显示的代码,但我已经更新了一些问题。
  • @Poles 问题中添加了一点动画代码

标签: ios uitableview uiview uiviewanimation


【解决方案1】:

我刚刚收到 Apple 开发者技术支持团队关于此问题的回复,这是他们的逐字回复(强调我的)

你好尼古拉斯,

感谢您联系 Apple 开发者技术支持 (DTS)。

您描述的行为和由此产生的限制是设计使然。

如果您认为 Apple 应该考虑另一种方法, 我们鼓励您提交增强请求,并提供以下信息 这个设计决定如何影响你,你希望看到什么 不同。

虽然没有承诺会改变行为,但它是 确保您对此事的想法被他人看到的最佳方式 负责决策的团队。

最好的问候,

Apple 开发者技术支持

看来我们只是不得不使用对tableView.setContentOffset(_:animated:)tableView.scrollToRow(at:at:animated:) 的简单调用。

【讨论】:

  • setContentOffset 或 scrollToRow 如何解决这个问题?
  • 它没有——我们只是坚持使用那些标准方法调用,而无法将其与自定义动画同步——这就是团队建议我们为其提交增强请求的原因。换句话说,您可以通过将调用移动到动画块之外的任何一种方法来“修复”它。
【解决方案2】:

好的,我会尝试提出我的版本,但我无法检查它,因为我没有看到你的项目。我没有尝试编译它,所以它可能有错误。

var navFrame = self.navigationController?.navigationBar.frame
navFrame.origin.y = isEditing ? -navFrame.size.height : 0

var frame = tableHeaderView.frame
frame.size.height = tableHeaderView.headerHeight(forEditing: isEditing)

UIView.animate(withDuration: 0.3, animations: {
    if isEditing{
        let point = CGPoint(x: 0, y: -self.topLayoutGuide.length)
        self.tableView.contentOffset = point
    }

    self.navigationController?.navigationBar.frame = navFrame

    tableHeaderView.frame = frame

    self.view.layoutIfNeeded()
}) { [weak self](completed:Bool) in
    //Do stuff
}

【讨论】:

  • 谢谢,有时间我会试试这个。但是有一个问题,为什么手动隐藏导航栏而不是像我已经使用的那样使用self.navigationController?.setNavigationBarHidden(isEditing, animated: true)?您认为这可能与问题有关?
  • @Sti 是的,可能动画冲突。
猜你喜欢
  • 2016-04-20
  • 2023-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-17
相关资源
最近更新 更多