我编写了一个自定义动画控制器来动画我的视图控制器转换。代码如下:
class PopupAnimationController: NSObject, UIViewControllerAnimatedTransitioning {
var backgroundColorView: UIView!
let duration: TimeInterval = 0.35
var dismiss = false
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return duration
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
if !dismiss {
animatePresentTransition(using: transitionContext)
} else {
animateDismissTransition(using: transitionContext)
}
}
func animatePresentTransition(using transitionContext: UIViewControllerContextTransitioning) {
guard let fromVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from),
let toVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to) else {
return
}
let containerView = transitionContext.containerView
let finalFrameForVC = transitionContext.finalFrame(for: toVC) // What is this about?
let bounds = UIScreen.main.bounds
let snapshotView = fromVC.view.snapshotView(afterScreenUpdates: false)
snapshotView?.frame = bounds
backgroundColorView = UIView(frame: bounds)
backgroundColorView.backgroundColor = UIColor.black.withAlphaComponent(0)
// Put the window at the bottom of the screen
toVC.view.frame = finalFrameForVC.offsetBy(dx: 0, dy: bounds.size.height)
// Layer out the views
containerView.addSubview(snapshotView!)
containerView.addSubview(backgroundColorView)
containerView.addSubview(toVC.view)
// The animation happens here
UIView.animate(withDuration: duration, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0, options: [], animations: {
self.backgroundColorView.backgroundColor = UIColor.black.withAlphaComponent(0.4)
toVC.view.frame = finalFrameForVC
}, completion: {
finished in
transitionContext.completeTransition(true)
})
}
func animateDismissTransition(using transitionContext: UIViewControllerContextTransitioning) {
guard let fromVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from) else {
return
}
UIView.animate(withDuration: duration, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0, options: [], animations: {
self.backgroundColorView.backgroundColor = UIColor.black.withAlphaComponent(0.0)
let bounds = UIScreen.main.bounds
fromVC.view.frame = fromVC.view.frame.offsetBy(dx: 0, dy: bounds.size.height)
}, completion: {
finished in
transitionContext.completeTransition(true)
})
}
}
我已在控制器中实现了UIViewControllerTransitioningDelegate
方法,这些方法将使用此转换:
extension PopupViewController: UIViewControllerTransitioningDelegate {
func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
transitionAnimator.dismiss = false
return transitionAnimator
}
func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
transitionAnimator.dismiss = true
return transitionAnimator
}
}
当我在动画中没有使用弹簧时(例如,阻尼设置为1),它可以完美地工作。但是,如果我在动画中包含弹簧,就像在此示例中一样,当控制器被解除时,屏幕会闪烁黑色:
不确定为什么会这样。关于我可能做错什么的任何想法在哪里?任何指针都将非常感谢!