UIView动画位置跳跃

时间:2017-02-06 18:34:00

标签: ios uiviewanimation

我有一个过渡动画,我需要让VC1上的项目移动到新位置,因为VC2被滑动到位。我在其他过渡方面做了这项工作没有任何问题,但对于这个我有一个我无法弄清楚的问题。

VC1 - 在中心有一个特定大小的图像 VC2 - 相同的图像以较小的尺寸放在右上角

所以我需要移动和扩展,因为我在转换中这样做,我认为正确的方法是:

  1. 从VC2转换图像并将其缩放以匹配VC1上的图像(使用转换)
  2. 隐藏VC1上的图片
  3. 将VC2中的图像动画回到.identity
  4. 当把东西移到左上角时,我成功完成了同样的事情。但是,当我执行此特定动画时,我看到我的VC2图像在动画开始到新位置时跳转。当我在比iPhone7更大或更小的设备/模拟器上工作时,我只看到这种跳跃,并且它根据屏幕宽度跳跃(左边是较小的,右边是较大的)。

    我已经在所有阶段注销了我的图像位置:

    transform from: (x:336.0, y:35.5, w:38.0) to: (x:160.0, y:180.5, w:66.0)
    xOffset: -176.0 yOffset: 145.0
    transform: CGAffineTransform(a: 1.0, b: 0.0, c: 0.0, d: 1.0, tx: -176.0, ty: 145.0)
    preanimation: (x: 160.0, y: 180.5
    currentPosition: (midX: 105.0, midY: 180.5)
    currentPosition: (midX: 112.312, midY: 174.476)
    

    此日志的第一行显示我将图像从(336,35)移动到(160,180.5)。第二行显示我的数学是正确的。第三行显示已创建的变换(缩放当前已关闭)。第四行显示我的图像在动画开始之前就在正确的位置。在cadisplaylink回调中返回最后2行,显示我的位置在动画开始之前跳转。

    有没有人碰到这样的事情?我有什么线索可以解决这个问题?我的图像全部放置在LayoutConstraints中,我的动画全部使用变换运行(在动画之前进行转换,然后动画回到.identity)。

    修改 一些添加的信息,当从横向开始我注意到我的原始帧是完全错误的:

    transform from: (x:336.0, y:35.5, w:38.0) to: (x:368.0, y:147.666666666667, w:66.0)
    xOffset: 32.0 yOffset: 112.166666666667
    transform: CGAffineTransform(a: 2.66666666666667, b: 0.0, c: 0.0, d: 2.66666666666667, tx: 32.0, ty: 112.166666666667)
    preanimation: (x: 368.0, y: 147.666666666667
    currentPosition: (midX: 729.0, midY: 127.666666666667)
    

    所以在这一点上,我认为问题在于,由于自动布局限制,我尝试同步的帧在动画之前是不正确的。当动画开始时,动画使用布局约束重新计算所有帧,然后应用我的变换使跳跃出现。

    EDIT2:

    我想我已经明白了。问题在于,我在动画中查看的视图还没有显示它的子视图,因此框架已关闭。通过在动画设置期间调用我的视图上的.setNeedsLayout().layoutIfNeeded(),我可以获得正确的位置以进行动画制作。

    这里好奇的是我第一次编辑时的相同日志,以及调用viewlifecycle方法时添加的日志:

    viewDidLoad <Chalkboard.SwipeToMoveViewController: 0x7fb1f760fb70>
    viewWillAppear <Chalkboard.SwipeToMoveViewController: 0x7fb1f760fb70>
    transform from: (x:336.0, y:35.5, w:38.0) to: (x:368.0, y:147.666666666667, w:66.0)
    xOffset: 32.0 yOffset: 112.166666666667
    transform: CGAffineTransform(a: 2.66666666666667, b: 0.0, c: 0.0, d: 2.66666666666667, tx: 32.0, ty: 112.166666666667)
    preanimation: (x: 368.0, y: 147.666666666667
    animation Block: (to.x: 368.0, to.y: 147.666666666667 - (from.x: 368.0, from.y: 147.666666666667
    viewWillLayoutSubviews <Chalkboard.SwipeToMoveViewController: 0x7fb1f760fb70>
    viewDidLayoutSubviews <Chalkboard.SwipeToMoveViewController: 0x7fb1f760fb70>
    currentPosition: (midX: 729.0, midY: 127.666666666667)
    

1 个答案:

答案 0 :(得分:0)

只是因为人们不想阅读文本墙来找到解决方案,问题是我在所有视图布局之前使用不同视图控制器中的视图位置。我假设在动画逻辑开始之前我的呈现视图控制器已经处理了整个视图生命周期,我错了。

动画通话订单:

  1. viewDidLoad中
  2. viewWillAppear中
  3. animateTransition
  4. viewWillLayoutSubviews
  5. viewDidLayoutSubviews
  6. 所以修复是手动调用setNeedsLayout()layoutIfNeeded()作为我的animateTransition的开头,这样我的观点位置都是已知的,可用于转换。