在 tableview 滚动和再次拖动 tableview 上动画 UIView 位置
Posted
技术标签:
【中文标题】在 tableview 滚动和再次拖动 tableview 上动画 UIView 位置【英文标题】:Animate UIView position on tableview scroll and again tableview drag 【发布时间】:2020-06-03 11:25:55 【问题描述】:我有一个项目列表,顶部有一个标题菜单。
当用户向上滚动菜单时,菜单也应该滚出屏幕,当他们返回列表顶部时,菜单应该是可见的。
与tableViewHeader
的行为方式大致相同。
但是,如果标题不在屏幕上并且用户在列表上结束了向下拖动,则此标题视图应该从顶部向下动画。如果用户随后在列表中向上拖动,则标题应以动画方式退出屏幕。
我已经实现了下面的第一部分,但是我正在努力实现动画效果。
我曾考虑为菜单使用 2 个视图,一个可以滚动,另一个可以为其位置设置动画,但是这感觉不对,我相信一定有更好的方法,而不会重复视图。
class TableViewScene: UIViewController
let data = Array(0...99)
var headerViewOneTopConstraint: NSLayoutConstraint!
var tableViewTopConstraint: NSLayoutConstraint!
lazy var headerViewOne: UIView =
let view = UIView(frame: .zero)
view.translatesAutoresizingMaskIntoConstraints = false
view.backgroundColor = .purple
return view
()
lazy var tableView: UITableView =
let view = UITableView(frame: .zero)
view.translatesAutoresizingMaskIntoConstraints = false
view.delegate = self
view.dataSource = self
view.tableFooterView = .init()
view.refreshControl = .init()
return view
()
override func viewDidLoad()
super.viewDidLoad()
navigationController?.navigationBar.isTranslucent = false
headerViewOneTopConstraint = headerViewOne.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor)
tableViewTopConstraint = tableView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 184)
[headerViewOne, tableView].forEach(view.addSubview)
NSLayoutConstraint.activate([
headerViewOneTopConstraint,
headerViewOne.leadingAnchor.constraint(equalTo: view.leadingAnchor),
headerViewOne.trailingAnchor.constraint(equalTo: view.trailingAnchor),
headerViewOne.heightAnchor.constraint(equalToConstant: 184),
tableViewTopConstraint,
tableView.leadingAnchor.constraint(equalTo: view.leadingAnchor),
tableView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
tableView.trailingAnchor.constraint(equalTo: view.trailingAnchor)
])
extension TableViewScene: UITableViewDelegate
func scrollViewDidScroll(_ scrollView: UIScrollView)
let offsetY = scrollView.contentOffset.y
headerViewOneTopConstraint.constant = max(-184, min(0, -offsetY))
tableViewTopConstraint.constant = 184 - max(0, offsetY)
我也尝试将其添加到视图中
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool)
let translation = scrollView.panGestureRecognizer.translation(in: scrollView.superview)
if translation.y > 0
headerViewOne.transform = .init(translationX: 0, y: 184)
else if translation.y < 0
headerViewOne.transform = .identity
这不起作用,而只是呈现一个黑色空间,用于在滚动到顶部时填充视图。
【问题讨论】:
你想要什么样的动画效果?你不喜欢你的 scrollViewDidScroll 实现什么?scrollViewDidScroll
工作完美,我对此非常满意,但是当用户例如在桌子的一半时,我无法将headerViewOne
重新进出视野。 headerViewOne
是一个“快速菜单”,他们应该能够通过向下拖动在列表顶部或列表中的任何位置查看它
在动画方面,只要简单的向下和向后滑动就完美了
【参考方案1】:
很难准确地说出您在寻找什么,但这可能对您有用。在这个实现中,当用户向上拖动时,标题将隐藏,当用户向下拖动时,标题将显示。无论滚动位置如何,都是如此。
我对您的一个约束进行了更改,以便将 tableView 的顶部固定到标题的底部:
tableViewTopConstraint = tableView.topAnchor.constraint(equalTo: headerViewOne.bottomAnchor)
我也在像这样跟踪标题的状态:
enum HeaderState
case hidden
case revealed
case hiding
case revealing
var headerState: HeaderState = .revealed
现在是滚动逻辑。如果滚动位置靠近顶部,那么我们要手动显示/隐藏标题。但是,如果滚动位置靠近底部或中心,那么我们希望为显示/隐藏功能设置动画。
func scrollViewDidScroll(_ scrollView: UIScrollView)
let translation = scrollView.panGestureRecognizer.translation(in: scrollView.superview)
if scrollView.contentOffset.y < 184
if translation.y > 0 && headerState != .revealed && headerState != .revealing
headerViewOneTopConstraint.constant = max(-184, min(0, -scrollView.contentOffset.y))
else if translation.y < 0
headerViewOneTopConstraint.constant = max(-184, min(0, -scrollView.contentOffset.y))
return
if translation.y > 0 && headerState == .hidden
self.headerState = .revealing
UIView.animate(withDuration: 0.4, animations:
self.headerViewOneTopConstraint.constant = 0
self.view.layoutIfNeeded()
, completion: _ in
self.headerState = .revealed
)
else if translation.y < 0 && headerState == .revealed
self.headerState = .hiding
UIView.animate(withDuration: 0.4, animations:
self.headerViewOneTopConstraint.constant = -184
self.view.layoutIfNeeded()
, completion: _ in
self.headerState = .hidden
)
试一试,看看它是否满足您的需求。
【讨论】:
啊是的,它很完美!非常感谢,非常有帮助以上是关于在 tableview 滚动和再次拖动 tableview 上动画 UIView 位置的主要内容,如果未能解决你的问题,请参考以下文章
使用 UIPanGesture 拖动 tableView/scrollView
element-ui的table组件,给某些列设置了fixed属性后,滚动条无法拖动
[Unity学习]使用ScrollRect实现自动滚动到底部显示实时消息,并在拖动的时候取消自动滚动,再次手动滑到底部,又继续自动滚动
[Unity学习]使用ScrollRect实现自动滚动到底部显示实时消息,并在拖动的时候取消自动滚动,再次手动滑到底部,又继续自动滚动
[Unity学习]使用ScrollRect实现自动滚动到底部显示实时消息,并在拖动的时候取消自动滚动,再次手动滑到底部,又继续自动滚动