UIScrollViewDelegate scrollViewDidScroll方法无法跟上高速滚动(轻弹)?

时间:2017-09-28 16:53:33

标签: ios uiscrollview uiscrollviewdelegate

我有一个带有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的方式吗?

1 个答案:

答案 0 :(得分:2)

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

        }

    }

}