ios - 底部工作表 ScrollView 平移和滚动
问题描述
我对 Apple 的 Maps 应用程序如何能够从工作表上的平移手势转换为 scrollView 或 tableView 中的滚动内容手势感兴趣。我把它作为重新创建它的第一次尝试。当工作表停靠时,我无法在不抬起手指的情况下从平移整个工作表到滚动内容。
有一些这样的问题和一些图书馆,但我还没有看到过渡部分的解决方案。
@objc func panGesture(recognizer: UIPanGestureRecognizer) {
let translation = recognizer.translation(in: view)
switch recognizer.state {
// ** Tracking starting offset
case .began: startingOffset = heightConstraint?.constant ?? 0
// ** Toggle panGesture and tableView to properly switch between gestures
case .changed:
let offset = startingOffset - translation.y
var minOffset: CGFloat = 0
mapView.alpha = 1 - (0.5 * (offset / maxOffset))
// This adds elasticity
if offset < 0 {
minOffset = -(0 - offset)/3
}
// ** Track bottom sheet with pan gesture by finding the diff
// be tween translation and starting offset, then constraint
// this value to be between our top margin and min height
let currentOffset = min(maxOffset, max(minOffset, offset))
heightConstraint?.constant = currentOffset
// ** `offset` == 0 means the sheet is minimized
// `offset` == `maxOffset` means the sheet is open
if currentOffset == 0 {
tableView.contentOffset = .zero
tableView.isScrollEnabled = false
} else if currentOffset == maxOffset {
panGesture.isEnabled = false
panGesture.isEnabled = true
tableView.isScrollEnabled = true
}
case .ended, .cancelled:
guard let offset = heightConstraint?.constant else { return }
// ** Handle last position - if nearer to the top finish out the
// animation to the top, and vice versa
var finalOffset: CGFloat = offset > maxOffset/2 ? maxOffset : 0
let velocity = recognizer.velocity(in: view).y
// ** Toggle tableView scrollability
// Handle "flick" action using `velocity`
if velocity < -100 {
finalOffset = maxOffset
tableView.isScrollEnabled = true
} else if offset > maxOffset/2 && velocity > 200 {
finalOffset = 0
tableView.isScrollEnabled = false
} else {
tableView.isScrollEnabled = offset > maxOffset/2
}
// Dismiss keyboard if dismissing sheet
if finalOffset == 0 {
_ = searchField.resignFirstResponder()
}
// ** Animate to top or bottom docking position when gesture ends
// or is cancelled
heightConstraint?.constant = finalOffset
UIView.animate(withDuration: 0.6, delay: 0, usingSpringWithDamping: 0.8, initialSpringVelocity: 0.2, options: [.curveEaseOut, .allowUserInteraction], animations: { [weak self] in
guard let strongSelf = self else { return }
strongSelf.view.layoutIfNeeded()
strongSelf.mapView.alpha = 1 - (0.5 * (finalOffset / strongSelf.maxOffset))
}, completion: nil)
default: ()
}
}
//UIScrollViewDelegate
func scrollViewDidScroll(_ scrollView: UIScrollView) {
guard let offset = heightConstraint?.constant else { return }
// ** Disable panning if scrollView isn't at the top
panGesture.isEnabled = tableView.contentOffset.y <= 0 || offset == 0
// ** Don't scroll if bottom sheet is panning down
if scrollView.contentOffset.y < 0 {
scrollView.isScrollEnabled = false
panGesture.isEnabled = true
}
}
帮助?
解决方案
推荐阅读
- javascript - 获取响应 blob 作为边缘中的对象 HTML 元素数据
- multiprocessing - 为什么不同核数的多处理代码的运行时间相同?
- java - 在模块 classes.jar 中发现重复的类
- android - 没有firebase可以使用GCP吗?
- reactjs - IIS 8.5 rewrite rule subdirectory and ReactJs
- couchdb - 在 cluster_finished 之后将新节点添加到现有的 CouchDB 集群
- python - 如何使用 tf.one_hot 计算一种热编码?
- bash - 如何在 Jenkins 运行的 bash 脚本中转义单引号?
- sql - Rails 按关联记录数选择
- ruby-on-rails - 在数据库设计中管理多个类别的最佳方法