当 UITableView 开始滚动时,动画视图

Posted

技术标签:

【中文标题】当 UITableView 开始滚动时,动画视图【英文标题】:Animate view out, when UITableView starts scrolling 【发布时间】:2018-03-07 15:44:12 【问题描述】:

我有一个视图控制器,它的视图包含标题视图和下面的 UITableView。 我不想将标题视图放在表格视图中以管理滚动,我希望它保持独立于表格视图。 但是我想在向下滚动表格视图时隐藏它,我当前的解决方案如下所示:

func scrollViewDidScroll(scrollView: UIScrollView) -> Void 
      //if contentOffset.y <= 0, table view is at the top, animate view in
      //else animate view out once

但是,由于我正在更改 layoutConstraint 的常量以移出视图,因此它会中断滚动并且还会弹出单元格,因为它突然有更多的空间可以显示。

我考虑在两个视图下方使用滚动视图,将标题视图移出并将触摸传递给表格视图。然而,带有自动布局内容的滚动视图有点让人头疼……

是否有任何关于此的主题或任何想法我可以做什么?基本上就像 Safari 中的导航栏一样,当您滚动内容时会滚动。

谢谢

【问题讨论】:

【参考方案1】:

为什么要视图独立于 tableview?这正是 tableview 擅长的。将视图作为常规视图放置在 tableview 中,向其中添加控件,然后将此视图和 tableview 与 IBOutlet 链接到视图控制器中。

然后只需将此视图设置为 tableview 的 tableHeaderView 即可获得所需的效果,标题视图将位于 tableview 内容的最顶部并随之滚动:

override func viewDidLoad() 
    super.viewDidLoad()
    headerView.layoutIfNeeded()
    headerView.frame.size = headerView.systemLayoutSizeFitting(UILayoutFittingCompressedSize)
    tableView.tableHeaderView = headerView

一旦要更新标题视图的内容,只需更改其内容并再次设置 tableHeaderView:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
    // Let's say myLabel is a label inside the headerView
    myLabel.text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus accumsan eros nec sem sagittis, vitae facilisis urna mattis."
    // Update the headerView size
    myLabel.preferredMaxLayoutWidth = myLabel.frame.width
    myLabel.layoutIfNeeded()
    headerView.layoutIfNeeded()
    headerView.frame.size = headerView.systemLayoutSizeFitting(UILayoutFittingCompressedSize)
    tableView.tableHeaderView = headerView

您也可以将视图放入自己的 Xib 文件中,并将其设置为 tableHeaderView:

let views = UINib(nibName: "HeaderView", bundle: Bundle.main).instantiate(withOwner: self, options: nil)
if views.count > 0, let headerView = views.first as? UIView 
    tableView.tableHeaderView = headerView

滚动视图委托的替代方案

在 tableview 上方放置一个视图并将其顶部约束连接到代码(例如 headerTopConstraint),然后执行以下操作:

func scrollViewDidScroll(_ scrollView: UIScrollView) 
    headerTopConstraint.constant += -scrollView.contentOffset.y
    if headerTopConstraint.constant > 0 
        headerTopConstraint.constant = 0
        return
    
    if -headerTopConstraint.constant > headerView.bounds.height 
        let diff = headerTopConstraint.constant + headerView.bounds.height
        headerTopConstraint.constant = -headerView.bounds.height
        scrollView.contentOffset = CGPoint(x: 0, y: -diff)
    
    else 
        scrollView.contentOffset = CGPoint(x: 0, y: 0)
    

标题视图将与表格视图一起向上滚动。滚动应该仍然感觉流畅。

【讨论】:

好吧,我想单独对待它,因为它的内容是从服务器获取的,所以我有时需要更新标题视图高度以反映该更改 我已经更新了代码以展示如何在最初设置后更新标题视图的内容。 我还添加了一个带有 scrollViewDidScroll 的示例。 @frin 谢谢。您的滚动视图委托代码运行良好。感谢您的努力。【参考方案2】:

当您在 UITableView 中为所有单元格显示 tableView 从中心反弹时,这种美感:

  override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) 
    cell.transform = CGAffineTransform(scaleX: 0.8, y: 0.8)
    UIView.animate(withDuration: 0.4) 
        cell.transform = CGAffineTransform.identity
    

【讨论】:

以上是关于当 UITableView 开始滚动时,动画视图的主要内容,如果未能解决你的问题,请参考以下文章

当文本字段开始编辑时停止 UITableView 滚动

UITableView 滚动时动画单元格

滚动时 UITableView 崩溃

启动 UITableView 滚动到底部

调用 reloadData 时 UITableView 有不需要的动画

在 UITableView 上为 layoutIfNeeded 设置动画而不为 UITableViewCells 设置动画