【问题标题】:UIScrollViewDelegate - animateWithDuration in scrollViewDidEndDragging is not working as expectedUIScrollViewDelegate - scrollViewDidEndDragging 中的 animateWithDuration 未按预期工作
【发布时间】:2015-10-02 09:34:17
【问题描述】:

我有一个 UIScrollView 并排有 2 个子视图/页面(水平内容大小 = 2 * 屏幕宽度 + 页面之间的装订线空间)。我想提高动画的完成速度,即在用户完成拖动并抬起手指之后。根据 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中的动画代码就会接管并完成翻译。我面临的问题是,当我在最左边或最右边的边缘向内拉视图时,似乎有一个额外的动画/跳跃。

例如,当contentOffset.x = 0(左边缘)时,如果我将视图向右拉 20 点并释放(即使在暂停一秒钟后),contentOffset.x 和 targetContentOffset.memory.x 将是 - 20,计算出的 self.targetX 将为 0。因此,在我的动画中,我希望页面在我抬起手指后立即以给定的速度向左移动 20 点。但我观察到的是,页面向右移动了几乎相同的量(拖动距离),然后从那里动画回到 0。移动速度如此之快,以至于我无法确定它是动画还是直接跳转。之后它会按照我的动画参数回退。

如前所述,向右跳跃似乎与拖动距离成正比,这表明我对动画开始前的“当前位置”的假设可能是错误的。但我无法弄清楚确切的原因。非常感谢您的帮助。设置是 ios 9.0、swift 2.0、xcode 7.0.1。

编辑 1:
我评论了 animateWithDuration(但保留了 scrollViewDidEndDragging)。动画停止,除了边缘区域,那里有一个默认动画拉回内容。进一步阅读指向bounce 属性。我怀疑这个默认动画与我提供的动画相冲突。

编辑 2:
bounce 动画似乎是罪魁祸首。在朝这个方向搜索时,我在 SO (Cancel UIScrollView bounce after dragging) 中遇到了另一个问题,描述了问题和可能的解决方案。

【问题讨论】:

  • 您已经在 scrollViewWillEndDragging:withVelocity:targetContenOffset: 中设置了 targetContentOffset,还需要在 scrollViewDidEndDragging:willDecelerate 中设置 contentOffset 吗?那不会做同样的事情吗?
  • 我没有明确更改 scrollViewWillEndDragging 中的 targetContentOffset (该值保持原样)。仅将值复制到实例变量 self.targetX 以在 scrollViewDidEndDragging 中使用。

标签: ios swift uiscrollviewdelegate


【解决方案1】:

问题似乎是因为反弹动画和自定义动画的排队。详情请阅读 - Cancel UIScrollView bounce after dragging。我不确定所选答案如何解决自定义持续时间的问题。还有另一种涉及子分类的解决方案。这在我的情况下也不起作用。不知道是不是因为iOS版本不同。

以下对我有用。这只是基本的sn-p。您可以对其进行增强以获得更好的动画曲线和速度处理。

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) })
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-06-04
    • 2022-01-24
    • 2015-05-11
    • 2020-05-15
    • 2014-10-31
    • 2018-02-12
    • 2014-01-20
    • 2015-01-13
    相关资源
    最近更新 更多