present到新控制器背景色半透明设置

我们开发中经常会遇到需要弹出一个弹窗且背景色半透明,但是我们设置modalPresentationStyleoverFullScreen背景色是半透明了,但是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

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容