gpt4 book ai didi

ios - UIScrollView 滚动时更改 contentInset

转载 作者:行者123 更新时间:2023-11-29 11:30:39 29 4
gpt4 key购买 nike

我正在尝试实现一个自定义顶部栏,它的行为类似于 iOS 11+ 大标题导航栏,当向下滚动内容时,该栏的大标题部分会折叠:

iOS navigation bar

不同之处在于我的栏需要一个自定义高度以及一个在滚动时不会折叠的底部部分。我设法让那部分工作:

My custom bar

该栏是使用 UIStackView 和一些非必需的布局约束实现的,但我相信它的内部实现不相关。最重要的是 bar 的高度与 scrollview 的顶部 contentInset 相关联。这些由 UIScrollViewDelegate.scrollViewDidScroll 方法中的 scrollview 的 contentOffset 驱动:

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 存储最小和最大条形高度

我遇到的一个问题是,当用户停止滚动 ScrollView 时,该栏可能最终会处于半折叠状态。再一次,让我们看看期望的行为: iOS default bar details

内容偏移量与紧凑高度或展开高度对齐,以“更近”为准。我试图在 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)")
}

效果远非完美: My custom bar details

当我查看打印输出时,它显示 targetContentOffset 已正确修改。然而,在应用程序中,内容偏移量仅捕捉到压缩高度而不是展开高度(您可以观察到大的“标题”标签最终被切成两半而不是回到“展开”位置。

我怀疑这个问题与用户滚动时更改 contentInset.top 有关,但我不知道如何解决这个问题。

这个问题有点难解释,所以我希望 GIF 能有所帮助。这是 repo 协议(protocol):https://github.com/AleksanderMaj/ScrollView

关于如何使 ScrollView /条形组合正确对齐压缩/扩展高度有什么想法吗?

最佳答案

我查看了您的项目并喜欢您的实现。

我在您的scrollViewWillEndDragging 方法中提出了一个解决方案,方法是在方法末尾添加以下代码:

    if abs(targetY) < abs(snappedTargetY) {
scrollView.setContentOffset(CGPoint(x: 0, y: snappedTargetY), animated: true)
}

基本上,如果向下滚动量不值得隐藏大标题(如果 targetY 小于 snappedTargetY,就会发生这种情况),那么只需滚动到 snappedTargetY 的值以显示大标题。

目前似乎可以正常工作,但如果您遇到任何错误或找到改进方法,请告诉我。

整个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

if abs(targetY) < abs(snappedTargetY) {
scrollView.setContentOffset(CGPoint(x: 0, y: snappedTargetY), animated: true)
}

print("Snapped: \(targetY) -> \(snappedTargetY)")
}

关于ios - UIScrollView 滚动时更改 contentInset,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53938079/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com