我正在尝试使用UIViewControllerAnimatedTransitioning
委托方法为viewControllers设置动画,我有一些问题。
我见过的所有示例代码都使用框架为视图设置动画,但是我使用的是autolayout,它在动画帧更改时给我带来了问题。
我希望以这种方式设置从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,动画效果不佳。
那么,你觉得我怎么能用约束做这个动画?
谢谢!
答案 0 :(得分:0)
您需要获取目标视图的参考视图,以设置转换动画。您的源视图和目标视图应该与约束相同。
使用snapShot获取视图以获取参考视图。
然后使用关键帧动画显示转换。在下面的示例代码中使用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)
})
}