SwiftUI 不透明度过渡分别淡化每个视图和子视图

问题描述 投票:0回答:1

TLDR:如何在淡入之前渲染整个子视图?

考虑以下代码片段:一个简单的白色视图和一个用于切换覆盖 FrontView 的按钮。 FrontView 是 2 个黑色视图的叠加,一个全屏视图和一个较小的视图。

struct ContentView: View {
    @State private var frontViewIsOpen = false
    
    var body: some View {
        ZStack {
            Color.white
                .zIndex(0)
            if frontViewIsOpen {
                FrontView()
                    .transition(.opacity)
                    .zIndex(1)
            }
            VStack {
                Spacer()
                Button("Toggle") {
                    frontViewIsOpen.toggle()
                }
            }
            .padding(.bottom, 50)
            .zIndex(2)
        }
        .animation(.linear(duration: 1), value: frontViewIsOpen)
        .ignoresSafeArea()
    }
}

struct FrontView: View {
    var body: some View {
        Color.black
            .overlay {
                Color.black.frame(width: 100, height: 100)
            }
    }
}

切换时,FrontView 在 1 秒内淡入。以下是 t=0、t=0.5 和 t=1 时的屏幕截图:

在整个动画过程中,内部 100pt 黑色视图清晰可见。我猜 SwiftUI 不仅会淡入 FrontView,还会淡入树中的所有子视图。在 t=0.5 时,FrontView alpha 为 0.5,内部视图也是 0.5,因此使用透明度时,两者的交集应为 0.75。

我在 UIKit 上重新创建了这个测试。当淡入/淡出视图时,UIKit 不会自动淡出子视图,从而导致过渡渲染如下:

我正在尝试在 SwiftUI 中重现 UIKit 转换行为。我尝试使用

.transaction { $0.animation = nil }
删除内部视图事务动画,或将内部视图过渡设置为
.identity
,但没有成功。

我有办法在转换之前渲染整个子视图吗?

swiftui rendering swiftui-animation swiftui-transition
1个回答
0
投票

只需将

.compositingGroup
添加到
FrontView

var body: some View {
    Color.black
        .overlay {
            Color.black.frame(width: 100, height: 100)
        }
        .compositingGroup() // <- HERE
}
© www.soinside.com 2019 - 2024. All rights reserved.