UIScrollViewDelegate scrollViewDidScroll 方法跟不上高速滚动(轻弹)?
Posted
技术标签:
【中文标题】UIScrollViewDelegate scrollViewDidScroll 方法跟不上高速滚动(轻弹)?【英文标题】:UIScrollViewDelegate scrollViewDidScroll method not keeping up with high-velocity scrolling (flick)? 【发布时间】:2017-09-28 16:53:32 【问题描述】:我有一个UIScrollView
和一个UIView
标头,它贴在滚动视图的顶部,并在用户向下滚动时从全尺寸缩小到小尺寸。当然,这些是通过滚动视图委托实现的:
// scroll view delegate
extension SomeViewController
// scroll view did scroll
public func scrollViewDidScroll(_ scrollView: UIScrollView)
let contentOffsetY = scrollView.contentOffset.y
// make banner sticky
banner.frame.origin.y = max(0, contentOffsetY)
// shrink banner
if contentOffsetY > 0 && contentOffsetY <= bannerHeight! - 64
banner.frame.size.height = bannerHeight! - contentOffsetY
bannerGraphic.frame = banner.bounds
效果很好...如果用户不高速滚动。如果用户轻弹以向下滚动(高速),代表似乎跟不上,并且横幅永远不会完全缩小(可能是 85-90%)。为了验证这一点,我将滚动视图的偏移量打印到控制台,并注意到当用户缓慢滚动时,控制台可能会打印 100 行当前偏移量。并且当用户快速滚动时,控制台可能会打印 25 行当前偏移量。代表根本无法跟上高速滚动。
有没有办法确保横幅在不考虑滚动速度的情况下缩小,或者这只是 UIKit
的方式?
【问题讨论】:
您希望banner.frame.size.height
至少 64 岁吗?还是应该缩小到零?
至少 64 个(状态栏 + 导航栏)
好的-并且...如果您在滚动视图内容一直位于顶部的情况下向下拉,那么.contentOffset.y < 0
,横幅是否应该从顶部向下移动?还是保持“固定”在顶部,并保持其原始大小?
横幅在下拉时不应保持固定
好的 - 看看我的回答。
【参考方案1】:
ScrollView 委托不会收到关于视图滚动的每一个点的通知。而且你真的不希望这样......这将是太多不必要的处理。
因此,在快速滚动时完全有可能出现较大的间隙。事实上,在一个快速测试中,我只是将.contentOffsetY
的值从 0 跳到 75 到 300...
您的代码很接近。你想要做的是在你超过你的最大值时处理这个条件。
试一试(我认为它只会插入并替换您的功能):
extension TestViewController: UIScrollViewDelegate
// scroll view did scroll
public func scrollViewDidScroll(_ scrollView: UIScrollView)
let contentOffsetY = scrollView.contentOffset.y
// make banner sticky
banner.frame.origin.y = max(0, contentOffsetY)
// if scrollView content is all the way at the top
// (or pulled down, waiting to "bounce back up")
if contentOffsetY <= 0
// set banner to original height
banner.frame.size.height = bannerHeight
bannerGraphic.frame = banner.bounds
else
// view has scrolled (user has dragged *up*)
// set banner height to originalHeight - y offset,
// but keep it a minimum of 64
banner.frame.size.height = max(bannerHeight! - contentOffsetY, 64)
bannerGraphic.frame = banner.bounds
【讨论】:
很高兴为您提供帮助:)以上是关于UIScrollViewDelegate scrollViewDidScroll 方法跟不上高速滚动(轻弹)?的主要内容,如果未能解决你的问题,请参考以下文章
在 UICollectionView 子类中实现 UIScrollViewDelegate
成为 UITableView 的 UIScrollViewDelegate 代表
从 UITableView 的子类访问 UIScrollViewDelegate
在 UICollectionView 中滚动时绕过 UIScrollViewDelegate