新建UIViewControllerAnimatedTransitioning的子类 由于要实现NSObjectProtocol 所以要继承NSObject
转场动画分为非交互性转场动画 和 交互性转场动画(手势)
只有在交互动画里面才有取消动画一说 !transitionContext.transitionWasCancelled 根据动画是否取消判断动画是否结束
let detailVC = storyboard?.instantiateViewController(withIdentifier: "DetailVc") as! ViewController
detailVC.transitioningDelegate = self
present(detailVC, animated: true, completion: nil)
extension MainViewController: UIViewControllerTransitioningDelegate {
//自定义动画
func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return PresentAnimation()
}
func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return DismissAnimation()
}
}
class PresentAnimation: NSObject,UIViewControllerAnimatedTransitioning {
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return 0.3
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
guard let fromVC = transitionContext.viewController(forKey: .from),
let toVC = transitionContext.viewController(forKey: .to),
let fromView = transitionContext.view(forKey: .from),
let toView = transitionContext.view(forKey: .to) else{ return }
let containerView = transitionContext.containerView
containerView.addSubview(toView)
//自定义动画
toView.alpha = 0
toView.transform = CGAffineTransform(translationX: containerView.frame.width, y: 0)
UIView.animate(
withDuration: transitionDuration(using: transitionContext),
animations: {
fromView.alpha = 0
fromView.transform = CGAffineTransform(translationX: -containerView.frame.width, y: 0)
toView.alpha = 1
toView.transform = .identity
}) { _ in
fromView.transform = .identity
toView.transform = .identity
transitionContext.completeTransition(true)
}
}
}
class DismissAnimation: NSObject,UIViewControllerAnimatedTransitioning {
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return 0.3
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
let containerView = transitionContext.containerView
guard let fromVC = transitionContext.viewController(forKey: .from),
let toVC = transitionContext.viewController(forKey: .to),
let fromView = transitionContext.view(forKey: .from),
let toView = transitionContext.view(forKey: .to) else{ return }
containerView.addSubview(toView)
toView.alpha = 0
// toView.transform = CGAffineTransform(translationX: -containerView.frame.width, y: 0)
UIView.animate(
withDuration: transitionDuration(using: transitionContext),
animations: {
toView.alpha = 1
toView.transform = .identity
fromView.alpha = 0
fromView.transform = CGAffineTransform(translationX: containerView.frame.width, y: 0)
}) { _ in
//fromView虽然被自动从containerView 里面移除了 但附在身上的transform属性还在 为了防止再次动画交错 要置空
fromView.transform = .identity
//虽然toViewdtransform在动画块里面置空了 但如果交互动画时用户取消转场了 就会被附上初始时定的transform 所以 为了不干扰下一次动画 这里也要置空
toView.transform = .identity
transitionContext.completeTransition(true)
}
}
}