我们开发中经常会遇到需要弹出一个弹窗且背景色半透明,但是我们设置modalPresentationStyle
为overFullScreen
背景色是半透明了,但是present时半透明弹窗从设备下面出现时不是渐变为半透明,是直接从下到上移上去,如下图:
Nov-16-2023 23-28-27.gif
下面我们定义要present的控制器的基类BaseSheetViewController
import UIKit
class BaseSheetViewController: UIViewController,UIViewControllerTransitioningDelegate {
init() {
super.init(nibName:nil,bundle: nil)
transitioningDelegate = self
modalPresentationStyle = .custom
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.clear
}
public func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
return CustomModayAlphaController(presentedViewController: presented, presenting: presenting)
}
}
class CustomModayAlphaController: UIPresentationController {
private var CustomFrameOfPresentedInContainerView = CGRect.zero
private var CustomSetFrameWhenPresentedView = false
override func presentationTransitionDidEnd(_ completed: Bool) {
super.presentationTransitionDidEnd(completed)
CustomSetFrameWhenPresentedView = completed
}
override func containerViewDidLayoutSubviews() {
super.containerViewDidLayoutSubviews()
CustomFrameOfPresentedInContainerView = frameOfPresentedViewInContainerView
}
override var presentedView: UIView? {
if CustomSetFrameWhenPresentedView {
super.presentedView?.frame = CustomFrameOfPresentedInContainerView
}
return super.presentedView
}
override func dismissalTransitionWillBegin() {
super.dismissalTransitionWillBegin()
CustomSetFrameWhenPresentedView = false
if let transitionCoordinator = presentingViewController.transitionCoordinator {
transitionCoordinator.animate(alongsideTransition: { [weak self] _ in
self?.containerView?.backgroundColor = .clear
}, completion: nil)
}
}
override func presentationTransitionWillBegin() {
super.presentationTransitionWillBegin()
containerView?.backgroundColor = .clear
if let coordinator = presentingViewController.transitionCoordinator {
coordinator.animate(alongsideTransition: { [weak self] _ in
self?.containerView?.backgroundColor = UIColor.black.withAlphaComponent(0.4)
}, completion: nil)
}
}
}
假如你要A present B,你可以使B继承于BaseSheetViewController
,直接A.present(B, animated: true),不需要设置modalPresentationStyle
,present的效果就达到了B背景色渐变出来了,效果如下:
Nov-16-2023 23-31-26.gif