我有一个UIScrollView,它通过设置内容偏移量(通过UIViewPropertyAnimator )自动滚动。自动滚动正在按预期工作,但我也希望能够中断动画滚动手动。
似乎是其中一个卖点 of UIViewPropertyAnimator
...dynamically在动画完成前修改它们
但是,它似乎不能很好地处理滚动视图(除非我在这里做错了什么)。
在大多数情况下,它是起作用的。当我滚动动画期间,它暂停,然后恢复一旦减速已经结束。然而,当我向底部滚动时,它的橡皮筋就好像它已经在内容的末尾了(即使它离内容很远)。这不是一个问题,同时滚动到顶部。
注意到这一点后,我检查了scrollView.contentOffset的值,并且它似乎卡在最大值+橡胶带偏移量。我找到了这个问题/答案,这似乎表明这可能是UIViewPropertyAnimator的一个bug。
我的代码如下:
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
}
}
}有什么地方明显我错了吗?或者我可以用什么方法让滚动视图停止向下滚动的橡皮筋?
发布于 2021-08-13 10:40:14
您可以添加点击手势识别器并调用此函数,
extension UIScrollView {
func stopDecelerating() {
let contentOffset = self.contentOffset
self.setContentOffset(contentOffset, animated: false)
}
}https://stackoverflow.com/questions/68658428
复制相似问题