首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >手动滚动由UIScrollView动画的UIViewPropertyAnimator

手动滚动由UIScrollView动画的UIViewPropertyAnimator
EN

Stack Overflow用户
提问于 2021-08-04 21:55:10
回答 1查看 307关注 0票数 4

我有一个UIScrollView,它通过设置内容偏移量(通过UIViewPropertyAnimator )自动滚动。自动滚动正在按预期工作,但我也希望能够中断动画滚动手动。

似乎是其中一个卖点 of UIViewPropertyAnimator

...dynamically在动画完成前修改它们

但是,它似乎不能很好地处理滚动视图(除非我在这里做错了什么)。

在大多数情况下,它是起作用的。当我滚动动画期间,它暂停,然后恢复一旦减速已经结束。然而,当我向底部滚动时,它的橡皮筋就好像它已经在内容的末尾了(即使它离内容很远)。这不是一个问题,同时滚动到顶部。

注意到这一点后,我检查了scrollView.contentOffset的值,并且它似乎卡在最大值+橡胶带偏移量。我找到了这个问题/答案,这似乎表明这可能是UIViewPropertyAnimator的一个bug。

我的代码如下:

代码语言:javascript
复制
private var maxYOffset: CGFloat = .zero
private var interruptedFraction: CGFloat = .zero

override func layoutSubviews() {
    super.layoutSubviews()
    
    self.maxYOffset = self.scrollView.contentSize.height - self.scrollView.frame.height
}

private func scrollToEnd() {
    let maxOffset = CGPoint(x: .zero, y: self.maxYOffset)
    let duration = (Double(self.script.wordCount) / Double(self.viewModel.wordsPerMinute)) * 60.0
    
    let animator = UIViewPropertyAnimator(duration: duration, curve: .linear) {
        self.scrollView.contentOffset = maxOffset
    }
    animator.startAnimation()
    self.scrollAnimator = animator
}

extension UIAutoScrollView: UIScrollViewDelegate {

    func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
        // A user initiated pan gesture will begin scrolling.
    
        if let scrollAnimator = self.scrollAnimator, self.viewModel.isScrolling {
            self.interruptedFraction = scrollAnimator.fractionComplete
            scrollAnimator.pauseAnimation()
        }
    }

    func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
        if let scrollAnimator = self.scrollAnimator, self.viewModel.isScrolling {
            scrollAnimator.startAnimation()
        }
    }

    func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
        if let scrollAnimator = self.scrollAnimator, self.viewModel.isScrolling {
            scrollAnimator.startAnimation()
        }
    }

    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        switch scrollView.panGestureRecognizer.state {
        case .changed:
            // A user initiated pan gesture triggered scrolling.
                    
            if let scrollAnimator = self.scrollAnimator {
                let fraction = (scrollView.contentOffset.y - self.maxYOffset) / self.maxYOffset
                let boundedFraction = min(max(.zero, fraction), 1)
            
                scrollAnimator.fractionComplete = boundedFraction + self.interruptedFraction
            }
        default:
        break
        }
    }
}

有什么地方明显我错了吗?或者我可以用什么方法让滚动视图停止向下滚动的橡皮筋?

EN

回答 1

Stack Overflow用户

发布于 2021-08-13 10:40:14

您可以添加点击手势识别器并调用此函数,

代码语言:javascript
复制
extension UIScrollView  {
    func stopDecelerating() {
        let contentOffset = self.contentOffset
        self.setContentOffset(contentOffset, animated: false)
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68658428

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档