UIScrollViewDelegate - scrollViewDidEndDragging 中的 animateWithDuration 未按预期工作
UIScrollViewDelegate - animateWithDuration in scrollViewDidEndDragging is not working as expected
我有一个 UIScrollView
,有 2 个子 views/pages 并排(水平内容大小 = 2 * 屏幕宽度 + 页间距 space)。我想提高动画的完成速度,即在用户完成拖动并抬起手指后。根据在 SO 中找到的建议,我实现了一个 UIScrollViewDelegate
如下。
class MyScrollViewDelegate: NSObject, UIScrollViewDelegate
{
var targetX: CGFloat = 0.0
func scrollViewWillEndDragging(scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>)
{
// I have not implemented the paging logic yet as I wanted to test the replacement animation first.
// Below code simply uses the suggested tagetOffset, but limiting the same between the valid min and max values
targetX = fmax(0, fmin(scrollView.contentSize.width - scrollView.frame.size.width, targetContentOffset.memory.x))
}
func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool)
{
UIView.animateWithDuration(0.25, animations: { scrollView.contentOffset = CGPointMake(self.targetX, 0) })
}
}
我的理解是,一旦拖动结束,scrollViewDidEndDragging
中我自己的动画代码将接管并完成翻译。我面临的问题是,当我在最左边或最右边的边缘向内拉视图时,似乎有一个额外的animation/jump。
例如,当 contentOffset.x = 0
(左边缘)时,如果我将视图向右拉 20 点并释放(即使在暂停一秒钟后),contentOffset.x & targetContentOffset.memory.x 将为 -20,计算出的 self.targetX 将为 0。因此,在我的动画中,我希望一旦我抬起手指,页面就会以给定的速度向左移动 20 点。但我观察到的是,页面向右移动了几乎相同的量(拖动距离),然后从那里动画回到 0。移动速度太快了,我无法确定它是动画还是直接跳转。然后跟着我的动画参数回退。
如前所述,向右跳跃似乎与拖动距离成正比,这表明我对动画开始前的 "current position" 的假设可能是错误的。但我无法弄清楚确切的原因。非常感谢您的帮助。设置为 ios 9.0,swift 2.0,xcode 7.0.1。
编辑 1:
我评论了 animateWithDuration(但保留了 scrollViewDidEndDragging)。动画停止,边缘区域除外,那里有一个默认动画将内容拉回来。进一步阅读指向 bounce
属性。我怀疑这个默认动画是否与我提供的动画发生冲突。
编辑 2:
bounce
动画似乎是罪魁祸首。在朝这个方向搜索时,我在 SO (Cancel UIScrollView bounce after dragging) 中遇到了另一个问题,描述了问题和可能的解决方案。
问题似乎是因为弹跳动画和自定义动画排队。详情请阅读-Cancel UIScrollView bounce after dragging。我不确定所选答案如何解决自定义持续时间的问题。还有另一种涉及子类化的解决方案。这对我来说也不起作用。不确定是否是因为 iOS 版本不同。
以下是对我有用的。这只是基本片段。您可以对其进行增强以获得更好的动画曲线和速度处理。
func scrollViewWillBeginDecelerating(scrollView: UIScrollView)
{
// below line seems to prevent the insertion of bounce animation
scrollView.setContentOffset(scrollView.contentOffset, animated: false)
// provide your animation with custom options
UIView.animateWithDuration(0.25, animations: { scrollView.contentOffset = CGPointMake(targetX, targetY) })
}
我有一个 UIScrollView
,有 2 个子 views/pages 并排(水平内容大小 = 2 * 屏幕宽度 + 页间距 space)。我想提高动画的完成速度,即在用户完成拖动并抬起手指后。根据在 SO 中找到的建议,我实现了一个 UIScrollViewDelegate
如下。
class MyScrollViewDelegate: NSObject, UIScrollViewDelegate
{
var targetX: CGFloat = 0.0
func scrollViewWillEndDragging(scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>)
{
// I have not implemented the paging logic yet as I wanted to test the replacement animation first.
// Below code simply uses the suggested tagetOffset, but limiting the same between the valid min and max values
targetX = fmax(0, fmin(scrollView.contentSize.width - scrollView.frame.size.width, targetContentOffset.memory.x))
}
func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool)
{
UIView.animateWithDuration(0.25, animations: { scrollView.contentOffset = CGPointMake(self.targetX, 0) })
}
}
我的理解是,一旦拖动结束,scrollViewDidEndDragging
中我自己的动画代码将接管并完成翻译。我面临的问题是,当我在最左边或最右边的边缘向内拉视图时,似乎有一个额外的animation/jump。
例如,当 contentOffset.x = 0
(左边缘)时,如果我将视图向右拉 20 点并释放(即使在暂停一秒钟后),contentOffset.x & targetContentOffset.memory.x 将为 -20,计算出的 self.targetX 将为 0。因此,在我的动画中,我希望一旦我抬起手指,页面就会以给定的速度向左移动 20 点。但我观察到的是,页面向右移动了几乎相同的量(拖动距离),然后从那里动画回到 0。移动速度太快了,我无法确定它是动画还是直接跳转。然后跟着我的动画参数回退。
如前所述,向右跳跃似乎与拖动距离成正比,这表明我对动画开始前的 "current position" 的假设可能是错误的。但我无法弄清楚确切的原因。非常感谢您的帮助。设置为 ios 9.0,swift 2.0,xcode 7.0.1。
编辑 1:
我评论了 animateWithDuration(但保留了 scrollViewDidEndDragging)。动画停止,边缘区域除外,那里有一个默认动画将内容拉回来。进一步阅读指向 bounce
属性。我怀疑这个默认动画是否与我提供的动画发生冲突。
编辑 2:
bounce
动画似乎是罪魁祸首。在朝这个方向搜索时,我在 SO (Cancel UIScrollView bounce after dragging) 中遇到了另一个问题,描述了问题和可能的解决方案。
问题似乎是因为弹跳动画和自定义动画排队。详情请阅读-Cancel UIScrollView bounce after dragging。我不确定所选答案如何解决自定义持续时间的问题。还有另一种涉及子类化的解决方案。这对我来说也不起作用。不确定是否是因为 iOS 版本不同。
以下是对我有用的。这只是基本片段。您可以对其进行增强以获得更好的动画曲线和速度处理。
func scrollViewWillBeginDecelerating(scrollView: UIScrollView)
{
// below line seems to prevent the insertion of bounce animation
scrollView.setContentOffset(scrollView.contentOffset, animated: false)
// provide your animation with custom options
UIView.animateWithDuration(0.25, animations: { scrollView.contentOffset = CGPointMake(targetX, targetY) })
}