当 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 开始滚动时,动画视图的主要内容,如果未能解决你的问题,请参考以下文章
调用 reloadData 时 UITableView 有不需要的动画
在 UITableView 上为 layoutIfNeeded 设置动画而不为 UITableViewCells 设置动画