【发布时间】:2019-05-25 01:43:31
【问题描述】:
我正在尝试实现一个自定义顶栏,其行为类似于 iOS 11+ 大标题导航栏,其中当向下滚动内容时,栏的大标题部分会折叠:
不同之处在于我的栏需要自定义高度以及滚动时不会折叠的底部。我设法让那部分工作:
该栏是使用 UIStackView 实现的,并带有一些非必需的布局约束,但我认为它的内部实现不相关。最重要的是bar的高度与scrollview的顶部contentInset相关联。这些是由滚动视图的contentOffset 在UIScrollViewDelegate.scrollViewDidScroll 方法中驱动的:
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let topInset = (-scrollView.contentOffset.y).limitedBy(topBarHeightRange)
// changes both contentInset and scrollIndicatorInsets
adjustTopContentInset(topInset)
// changes top bar height
heightConstraint?.constant = topInset
adjustSmallTitleAlpha()
}
topBarHeightRange 存储最小和最大条形高度
我遇到的一个问题是,当用户停止滚动滚动视图时,栏可能最终处于半折叠状态。再次,让我们看看所需的行为:
内容偏移量捕捉到紧凑或展开高度,以“更接近”为准。我试图在UIScrollViewDelegate.scrollViewWillEndDragging 方法中实现同样的效果:
func scrollViewWillEndDragging(_ scrollView: UIScrollView,
withVelocity velocity: CGPoint,
targetContentOffset: UnsafeMutablePointer<CGPoint>) {
let targetY = targetContentOffset.pointee.y
// snaps to a "closer" value
let snappedTargetY = targetY.snappedTo([topBarHeightRange.lowerBound, topBarHeightRange.upperBound].map(-))
targetContentOffset.pointee.y = snappedTargetY
print("Snapped: \(targetY) -> \(snappedTargetY)")
}
当我查看打印输出时,它显示targetContentOffset 已正确修改。然而,在应用程序中,视觉上的内容偏移量仅捕捉到紧凑高度而不是展开高度(您可以观察到大的“标题”标签最终被切成两半而不是回到“展开”位置。
我怀疑此问题与在用户滚动时更改 contentInset.top 有关,但我不知道如何解决此问题。
解释这个问题有点困难,所以我希望 GIF 能有所帮助。这是回购:https://github.com/AleksanderMaj/ScrollView
任何想法如何使滚动视图/栏组合正确对齐到紧凑/展开高度?
【问题讨论】:
-
UidynamicItem 可能是你需要实现的
-
谢谢。我对 UIDynamics 的了解非常模糊。您能否简要(至少在概念上)描述这种实现将如何工作?
-
@AleksanderMaj 你有没有想过解决这个问题?
标签: ios uiscrollview uikit uiscrollviewdelegate