SwiftUI 作用于根控制器上的弹窗

2023-03-13  本文已影响0人  西风那个吹呀吹
  1. 创建根控制器管理类
class RootViewController: UIViewController {
    
    static let shared = RootViewController()
    
    var rootController: UIViewController? {
        get {
            let scences = UIApplication.shared.connectedScenes
            let windowScence = scences.first as? UIWindowScene
            let window = windowScence?.windows.first
            let viewController = window?.rootViewController
            return viewController
        }
    }
}
  1. 扩展里实现弹窗和消失事件
extension RootViewController {
    
    func present<Content: View>(@ViewBuilder content: () -> Content) {
        let toPresent = UIHostingController(rootView: AnyView(EmptyView()))
        toPresent.modalPresentationStyle = .overCurrentContext
        toPresent.modalTransitionStyle = .crossDissolve
        toPresent.view.backgroundColor = .clear
        toPresent.rootView = AnyView(content())
        
        rootController?.present(toPresent, animated: false)
    }
    
    func dismiss(animated: Bool = true) {
        rootController?.dismiss(animated: animated)
    }
}
  1. 写一个要弹的窗口视图,弹出与消失动画可根据需求去设置
struct PresentTestView: View {
    
    @State var isShow: Bool = false
    
    var body: some View {
        
        ZStack {
            
            Color.black.opacity(0.3).ignoresSafeArea().onTapGesture {
                
                // 内容先消失
                withAnimation {
                    isShow = false
                }
                
                // 随后页面消失
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
                    RootViewController.shared.dismiss(animated: true)
                }
            }
            
            Text("我是根控制器上的弹窗")
                .font(.system(.title))
                .padding(15)
                .frame(width: 300, height: 200)
                .foregroundColor(.black)
                .background(Color.yellow)
                .cornerRadius(10)
                .scaleEffect(isShow ? 1 : 0)
                .rotationEffect(.degrees(isShow ? 360 : 0))
                .opacity(isShow ? 1 : 0)
        }
        .onAppear {
            withAnimation(.easeIn(duration: 0.2)) {
                isShow = true
            }
        }
    }
}
  1. 最后,可在任何地方(View 或 ViewModel)调用根控制器管理类弹出你所写的弹窗视图
RootViewController.shared.present {
    PresentTestView()
}
上一篇下一篇

猜你喜欢

热点阅读