复制用于自定义控件的 SwiftUI GraphicalDatePickerStyle 的背景模糊

rus*_*ish 5 forms controls ios swift

我正在尝试开发一个自定义控件,用于在行为方式与 SwiftUI 的 DatePicker 类似的表单中使用(在表单中,它默认为 GraphicalDatePickerStyle)。

苹果的控件以模式方式显示日历和时间选择器,背景模糊。我可以使用 .fullScreenCover 修饰符来管理模式演示。通过将 UIVisualEffectView 添加到显示控件的背景也可以实现背景模糊。然而,即使使用系统默认提供的最轻选项,以这种方式应用的模糊也太过严厉。我对通过 DispatchQueue.main.async 修改超级视图背景也不满意 - 它有效,但让我感到不舒服。

有什么办法可以更接近Apple的实现吗?我尝试添加活力效果层并没有取得任何成果,并且根据文档,您不应该触摸 UIEffectViews 的 alpha ...

视觉效果(期望和当前迭代)的代码和比较如下:

import SwiftUI

struct ContentView: View {
    @State private var isPresented = false
    @State private var interval: TimeInterval = 0
    
    var body: some View {
        Form {
            Text("Row")
            Text("Row")
            Text("Row")
            Text("Row")
            
            DatePicker("Date", selection: .constant(Date()))
            
            Button("Present custom control") {
                self.isPresented.toggle()
            }
            .fullScreenCover(isPresented: $isPresented) {
                ZStack {
                    Color.white.opacity(0.1)
                        .edgesIgnoringSafeArea(.all)
                    // below is a placeholder for the custom control
                    Button("Dismiss") { isPresented.toggle() }
                        .frame(width: 200, height: 200)
                        .background(Color.white)
                        .cornerRadius(16)
                }
                .background(BackgroundBlurView())
            }
            
            Text("Other stuff here")
                .background(Color.red)
        }
    }
}

struct BackgroundBlurView: UIViewRepresentable {
    func makeUIView(context: Context) -> UIView {
        let view = UIVisualEffectView(effect: UIBlurEffect(style: .systemUltraThinMaterial))
        // this works but it looks a bit hacky... code smell?
        DispatchQueue.main.async {
            view.superview?.superview?.backgroundColor = .clear
        }
        return view
    }
    
    func updateUIView(_ uiView: UIView, context: Context) {
        // nothing needed here
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        Group {
            ContentView()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

表单(点击控件之前) 表单(点击控件之前)

DatePicker 应用的背景模糊 DatePicker 应用的背景模糊

我的尝试-不是遥不可及! 当前的尝试 - 明显模糊并失去活力

Sto*_*oic 0

首先,您提供的示例中的苹果模糊似乎也有一个.brightness修改器,可以使背景变暗。(您可以通过添加.brightness(- (some number)).

其次,您可以使用.blur()修改器,您可以在其中传递自定义模糊量。另一个解决方案是使用Apple的超级方便的Material. 有几种不同的材料,您应该将它们传递到您的ZStack而不是使用中Color.white.opacity(0.1),这看起来像这样:

ZStack {
    Material.ultraThin

    //rest of view
}
Run Code Online (Sandbox Code Playgroud)