ios - 使用自动布局约束对 viewController 过渡进行动画处理 (Swift)

标签 ios swift xcode autolayout constraints

我正在尝试使用 UIViewControllerAnimatedTransitioning 委托(delegate)方法对 viewController 进行动画处理,但我有一些问题。

我见过的所有示例代码都使用框架来对 View 进行动画处理,但我使用的是自动布局,它在对框架更改进行动画处理时给我带来了问题。

有这两种观点: First View Controller Second View Controller

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

Animation

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

    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,动画效果不佳。

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

谢谢!

最佳答案

您需要使用“目标” View 的引用 View 来为过渡设置动画。您的源 View 和目标 View 应具有相同的约束排列。

拍摄 View 快照以获取引用 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)
        })

    }

关于ios - 使用自动布局约束对 viewController 过渡进行动画处理 (Swift),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49412922/

相关文章:

ios - 计算CGPoint是否在线段上?

ios - 无法将类型 'SecCertificate' 的值转换为预期的参数类型 'UnsafeMutablePointer<UnsafeRawPointer?>!'

ios - 标题显示 3 个点 "..."而不是切换按钮中的字符串

ios - 如何计算文件夹的大小?

ios - 将多个图像作为 PFFiles 添加到解析数组

swift - Apple 的 Swift 数据类型绑定(bind)

ios - 3D Touch Peek 将屏幕变白

objective-c - iOS UI 自定义按钮图片

xcode - Bool 不是 ObjCBool​​ 的子类型 - swift 2 beta 5

ios - 为什么每当我使用 Search Display Controller 时底层的 UIViewTable 都会显示