SwiftUI 中透明和模糊的 fullScreenCover 模式?

roo*_*far 3 swiftui

我是在我的 SwiftUI 项目中显示模式的 fullScreenCover。

但是,我需要显示具有透明和模糊背景的模态。

但我似乎根本无法实现这一目标。

这是我的代码:

.fullScreenCover(isPresented: $isPresented) {
                       VStack(spacing: 20) {
                           Spacer()
                               .frame(maxWidth: .infinity, minHeight: 100)
                               .background(Color.black)
                               .opacity(0.3)
                           
                           //Text("modal")
                       }
                       .background(SecondView())     // << helper !!
                   }
Run Code Online (Sandbox Code Playgroud)

我在同一个视图上有这个:

struct BackgroundBlurView: UIViewRepresentable {
    func makeUIView(context: Context) -> UIView {
        let view = UIVisualEffectView(effect: UIBlurEffect(style: .light))
        DispatchQueue.main.async {
            view.superview?.superview?.backgroundColor = .clear
        }
        return view
    }

    func updateUIView(_ uiView: UIView, context: Context) {}
}
Run Code Online (Sandbox Code Playgroud)

上面的代码将打开全屏模式,但它根本不透明或模糊。

这就是我得到的:

在此输入图像描述

我还需要做些什么吗?

参考我从哪里获得上述代码:

SwiftUI:全屏覆盖的半透明背景

Raj*_*han 5

@Asperi这里的答案是完全正确的。只需要添加 alpha 来模糊视图即可。

struct BackgroundBlurView: UIViewRepresentable {
    func makeUIView(context: Context) -> UIView {
        let view = UIVisualEffectView(effect: UIBlurEffect(style: .light))
        view.alpha = 0.5 //< --- here
        DispatchQueue.main.async {
            view.superview?.superview?.backgroundColor = .clear
        }
        return view
    }
    
    func updateUIView(_ uiView: UIView, context: Context) {}
}
Run Code Online (Sandbox Code Playgroud)

另一种方法是使用 ViewControllerHolder参考链接

struct ViewControllerHolder {
    weak var value: UIViewController?
}

struct ViewControllerKey: EnvironmentKey {
    static var defaultValue: ViewControllerHolder {
        return ViewControllerHolder(value: UIApplication.shared.windows.first?.rootViewController)
    }
}

extension EnvironmentValues {
    var viewController: UIViewController? {
        get { return self[ViewControllerKey.self].value }
        set { self[ViewControllerKey.self].value = newValue }
    }
}

extension UIViewController {
    func present<Content: View>(backgroundColor: UIColor = UIColor.clear, @ViewBuilder builder: () -> Content) {
        let toPresent = UIHostingController(rootView: AnyView(EmptyView()))
        toPresent.view.backgroundColor = backgroundColor
        toPresent.modalPresentationStyle = .overCurrentContext
        toPresent.modalTransitionStyle = .coverVertical
        toPresent.rootView = AnyView(
            builder()
                .environment(\.viewController, toPresent)
        )
        
        //Add blur efect
        let blurEfect = UIVisualEffectView(effect: UIBlurEffect(style: .dark))
        blurEfect.frame = UIScreen.main.bounds
        blurEfect.alpha = 0.5
        toPresent.view.insertSubview(blurEfect, at: 0)
        self.present(toPresent, animated: true, completion: nil)
    }
}
Run Code Online (Sandbox Code Playgroud)
struct ContentViewNeo: View {
    @Environment(\.viewController) private var viewControllerHolder: UIViewController?
    
    var body: some View {
        VStack {
            Text("Background screen")
            Button("Open") {
                viewControllerHolder?.present(builder: {
                    SheetView()
                })
            }
        }
    }
}

struct SheetView: View {
    var body: some View {
        Text("Sheet view")
            .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)
    }
}
Run Code Online (Sandbox Code Playgroud)