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
,但没有成功。
我有办法在转换之前渲染整个子视图吗?
只需将
.compositingGroup
添加到 FrontView
:
var body: some View {
Color.black
.overlay {
Color.black.frame(width: 100, height: 100)
}
.compositingGroup() // <- HERE
}