如何仅将 SwiftUI 不透明度应用于父视图?

bod*_*ich 6 swift swiftui

将不透明度应用于 SwiftUI 中的视图,并将其通过层次结构向下传递,看起来它的工作原理有点环境值。当每个子视图独立地受到不透明度影响时,它会导致该行为。无论我们将黄色圆圈与叠加层、背景还是放在 ZStack 内。

在此输入图像描述

我们怎样才能使不透明度只影响父视图,就像它在 UIKit 中的行为一样,这样整个视图及其所有内容都将变成半透明的单个实体对象?

struct OpacityTest: View {
    var body: some View {
        HStack(spacing: 30) {
            buttonContent
                .opacity(0.5)

            Button(action: {}) {
                buttonContent
            }
        }
    }
    
    var buttonContent: some View {
        Image(systemName: "calendar.circle")
            .resizable()
            .frame(width: 65, height: 65)
            .overlay(
                Circle()
                    .fill(Color.yellow)
                    .frame(width: 40, height: 40)
                    .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topTrailing)
            )
    }
}

struct OpacityTest_Preview: PreviewProvider {
    static var previews: some View {
        OpacityTest()
    }
}
Run Code Online (Sandbox Code Playgroud)

更新: 正如 ChrisR 回答的那样, .drawingGroup() 完成了这项工作并部分解决了问题,但直到所有内容都在父视图边界内。一旦我们向覆盖层内的视图添加偏移量,它就会被裁剪。有机会避免吗?

.overlay(
    Circle()
        .fill(Color.yellow)
        .frame(width: 40, height: 40)
        .offset(x: 10, y: -10) //This modifier brakes the drawingGroup
        .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topTrailing)
    )
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

bod*_*ich 11

添加即可.compositingGroup()完成工作。它使外部修饰符仅在顶层起作用,而不是通过层次结构传递。也不会裁剪任何带有偏移的子视图,并保留原始框架进行布局。

var buttonContent: some View {
    Image(systemName: "calendar.circle")
        .resizable()
        .frame(width: 65, height: 65)
        .overlay(
            Circle()
                .fill(Color.yellow)
                .frame(width: 40, height: 40)
                .offset(x: 10, y: -10)
                .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topTrailing)
        )
        .compositingGroup() //here
}
Run Code Online (Sandbox Code Playgroud)