1.设置transitioningDelegate,modalPresentationStyle
let presentTransitionDelegate = SDEModalTransitionDelegate()
let toVC = segue.destination as! PresentedViewController
/// 设置 transitioningDelegate
toVC.transitioningDelegate = presentTransitionDelegate
toVC.modalPresentationStyle = .custom
2.实现transitioningDelegate
class SDEModalTransitionDelegate: NSObject, UIViewControllerTransitioningDelegate {
func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return OverlayAnimationController()
}
func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return OverlayAnimationController()
}
/// presentationController 定制 presentedView 的外观:设定 presentedView 的尺寸以及在 containerView 中添加自定义视图并为这些视图添加动画
func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
return OverlayPresentationController(presentedViewController: presented, presenting: presenting)
}
}
3.实现OverlayAnimationController:UIViewControllerAnimatedTransitioning
class OverlayAnimationController: 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: UITransitionContextViewControllerKey.from), let toVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to) else {
return
}
let fromView = fromVC.view
let toView = toVC.view
let duration = self.transitionDuration(using: transitionContext)
if toVC.isBeingPresented {
containerView.addSubview(toView!)
/*
let toViewWidth = containerView.frame.width * 2 / 3, toViewHeight = containerView.frame.height * 2 / 3
toView?.center = containerView.center
toView?.bounds = CGRect(x: 0, y: 0, width: 1, height: 1)//toViewHeight
*/
toView?.alpha = 0
//.curveEaseInOut
UIView.animate(withDuration: duration, delay: 0, options: [], animations: {
/*
toView?.bounds = CGRect(x: 0, y: 0, width: toViewWidth, height: toViewHeight)
*/
toView?.alpha = 1
}, completion: { _ in
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
})
}
// Dismissal 转场中不要将 toView 添加到 containerView
if fromVC.isBeingDismissed {
let fromViewHeight = fromView?.frame.height
UIView.animate(withDuration: duration, animations: {
// fromView?.bounds = CGRect(x: 0, y: 0, width: 1, height: fromViewHeight!)
fromView?.alpha = 0
}, completion: { _ in
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
})
}
}
}
4.presentationController 定制 presentedView 的外观:设定 presentedView 的尺寸以及在 containerView 中添加自定义视图并为这些视图添加动画
OverlayPresentationController
class OverlayPresentationController: UIPresentationController {
let dimmingView = UIView()
override func presentationTransitionWillBegin() {
containerView?.addSubview(dimmingView)
let dimmingViewInitailWidth = containerView!.frame.width * 2 / 3, dimmingViewInitailHeight = containerView!.frame.height * 2 / 3
dimmingView.backgroundColor = UIColor(white: 0.0, alpha: 0.5)
dimmingView.center = containerView!.center
dimmingView.bounds = CGRect(x: 0, y: 0, width: dimmingViewInitailWidth , height: dimmingViewInitailHeight)
_ = presentedViewController.transitionCoordinator?.animate(alongsideTransition: {
_ in
self.dimmingView.bounds = self.containerView!.bounds
}, completion: nil)
}
override func dismissalTransitionWillBegin() {
_ = presentedViewController.transitionCoordinator?.animate(alongsideTransition: { _ in
self.dimmingView.alpha = 0.0
}, completion: nil)
}
override func containerViewWillLayoutSubviews(){
dimmingView.center = containerView!.center
dimmingView.bounds = containerView!.bounds
let width = containerView!.frame.width * 2 / 3, height = containerView!.frame.height * 2 / 3
presentedView?.center = containerView!.center
presentedView?.bounds = CGRect(x: 0, y: 0, width: width, height: height)
}
}
参考:blog.devtang.com/2016/03/13/… 参考demo:github.com/seedante/iO… 参考:www.jianshu.com/p/96af57be1…