【问题标题】:Animate viewController transition with AutoLayout constraints (Swift)使用 AutoLayout 约束 (Swift) 动画 viewController 过渡
【发布时间】:2018-03-21 17:26:29
【问题描述】:

我正在尝试使用 UIViewControllerAnimatedTransitioning 委托方法为 viewController 设置动画,但我有一些问题。

我见过的所有示例代码都使用框架来为视图设置动画,但我使用的是自动布局,它在为框架更改设置动画时给我带来了问题。

有这两种观点:

我想以这种方式动画从 firstVC 到 secondVC 的过渡:

所以,这是我用来做这个动画的代码:

    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {

    let containerView = transitionContext.containerView
    let fromVC = transitionContext.viewController(forKey: .from)! as! CustomView
    let toView = transitionContext.view(forKey: .to)!
    //let cell = fromVC.currentCell //Access to the pressed cell (if needed)

    toView.frame = fromVC.currentFrame //currentFrame is the cell frame saved on fromVC

    toView.autoresizingMask = containerView.autoresizingMask
    toView.layoutIfNeeded()

    containerView.addSubview(toView)

    UIView.animate(withDuration: duration, animations: {

        toView.frame = containerView.frame
        toView.layoutIfNeeded()
    }, completion: { _ in

        transitionContext.completeTransition(true)
    })
}

如您所见,由于帧修改和使用 AutoLayout,动画效果不佳。

那么,你认为我可以如何在有约束的情况下制作这个动画?

谢谢!

【问题讨论】:

  • 如果你可以分享,我可以检查你的布局。
  • 我无法编辑我的问题,但我发现了一些奇怪的东西。如果我在标签上放置一个背景颜色,我可以看到如何遵守约束,但文本从右到左显示,而不是 textAlignment = .center

标签: ios swift xcode autolayout constraints


【解决方案1】:

您需要使用目标视图的参考视图来为您的过渡设置动画。您的源视图和目标视图应以相同的方式排列并带有约束。

以 snapShot for view 获取参考视图。

然后使用关键帧动画来显示过渡。像下面的示例代码一样使用 alpa 动画来使过渡感觉连续!

    var originFrame: CGRect! 
    // Orginal frame of card view(starting frame)
    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {

        guard let fromVC = transitionContext.viewController(forKey: .from),
            let toVC = transitionContext.viewController(forKey: .to),
            let snapshot = toVC.view.snapshotView(afterScreenUpdates: true)
            else {
              return
        }

        let containerView = transitionContext.containerView
        let finalFrame = transitionContext.finalFrame(for: toVC)

        snapshot.frame = originFrame
        snapshot.layer.cornerRadius = CardViewController.cardCornerRadius
        snapshot.layer.masksToBounds = true

        containerView.addSubview(toVC.view)
        containerView.addSubview(snapshot)
        toVC.view.isHidden = true
        fromVC.view.alpha = 1
        snapshot.alpha = 0
        let duration = 0.6

        UIView.animateKeyframes(
            withDuration: duration,
            delay: 0,
            options: .calculationModeCubic,
            animations: {
              UIView.addKeyframe(withRelativeStartTime: 0.0, relativeDuration: 1/2) {
                  fromVC.view.alpha = 1
              }

              UIView.addKeyframe(withRelativeStartTime: 0.0, relativeDuration: 1) {
                  snapshot.frame = finalFrame
                  fromVC.view.alpha = 0
                  snapshot.alpha = 1
              }
        },
          completion: { _ in
              toVC.view.isHidden = false
              snapshot.removeFromSuperview()
              fromVC.view.layer.transform = CATransform3DIdentity
              transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
        })

    }

【讨论】:

  • 纯代码答案很少有帮助。你能解释我们应该从你的代码中学到什么吗?
猜你喜欢
  • 2019-02-21
  • 1970-01-01
  • 2017-12-06
  • 1970-01-01
  • 2015-12-16
  • 2016-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多