具有清晰背景的SwiftUI视觉模糊效果

cqoc49vn  于 2023-10-15  发布在  Swift
关注(0)|答案(1)|浏览(82)

有没有办法让

.background(.ultraThinMaterial)

在SwiftUI中没有背景颜色?它似乎有一些光白色暗淡的背景,因为如果它只是模糊的背景单独,它不应该显示任何颜色,只有当内容是滚动后面。
iOS模拟器:

预期结果:

xwbd5t1u

xwbd5t1u1#

这里有两个可能的解决方法。

1.有条件展示物料

你在问题中说:
它不应该显示任何颜色,只有当内容滚动到后面时
因此,正如评论中所建议的那样,您可以根据实际滚动到其后面的内容来设置材料背景。如果你应用withAnimation的变化,那么它工作得很好:

@State private var withMaterialBackground = false

var body: some View {
    ZStack(alignment: .top) {
        ScrollView {
            content
                .padding(.top, 100)
                .background {
                    GeometryReader { proxy in
                        Color.clear
                            .onChange(of: proxy.frame(in: .named("ScrollView")).minY) { oldVal, newVal in
                                if withMaterialBackground != (newVal < 0) {
                                    withAnimation {
                                        withMaterialBackground.toggle()
                                    }
                                }
                            }
                    }
                }
        }
        .coordinateSpace(name: "ScrollView")

        header
            .background {
                if withMaterialBackground {
                    Rectangle()
                        .fill(.ultraThinMaterial)
                        .ignoresSafeArea()
                }
            }
    }
}

2.使用较暗的背景来补偿材质效果

如果将材质后面的内容的背景设置得更暗,则由材质效果引起的背景较浅阴影几乎可以消除,或者至少可以显著减少。换句话说,您可以通过在该区域设置较暗的背景来补偿较浅的阴影。
使背景变暗是针对暗模式运行时的情况。在光线模式下,它以另一种方式工作,材料背后的内容需要变得更轻。
在模拟器上测试,我发现这些组合工作得很好:

  • 在黑暗模式下,Color(white: 0.15)的主背景与Color.black的材料后面。
  • 在灯光模式下,Color(white: 0.91)的主背景与Color.white的材料后面。

就像这样:

@Environment(\.colorScheme) private var colorScheme: ColorScheme
let headerHeight: CGFloat = 175

var body: some View {
    ZStack(alignment: .top) {
        Color.clear

        content
            .background(alignment: .top) {
                Color(white: colorScheme == .dark ? 0.0 : 1.0)
                    .ignoresSafeArea()
                    .frame(height: headerHeight, alignment: .top)
            }

        header
            .frame(height: headerHeight, alignment: .top)
            .background(.ultraThinMaterial)
    }
    .background(Color(white: colorScheme == .dark ? 0.15 : 0.91))
}

相关问题