首页 > 解决方案 > 显示 .sheet 时为 SwiftUI 视图设置动画

问题描述

我有一张SheetAnimationView我想从中显示一张名为SheetContentView.

当工作表出现时,我想显示其内容的过渡动画(在内容出现时启动动画)但无法使其工作。理想情况下,VStack 中的所有 3 个视图应该同时结束它们的动画。

工作表内容视图:

struct SheetContentView: View {
    @Binding var showSheet: Bool
    
    var body: some View {
        VStack(spacing: 8) {
            Text("A great content of my new sheet")
            Label("still not done", systemImage: "guitars")
            Text("I'm done now")
        }
        .transition(.asymmetric(insertion: .scale, removal: .opacity)) // <--- I want this to work
        .animation(Animation.easeInOut(duration: 2)) // <--- for 2 seconds
        
    }
}

工作表动画视图:

struct SheetAnimationView: View {
    @State var showSheet: Bool = false
    
    var body: some View {
        Button("show my sheet with animated content (hopefully)") {
            showSheet = true
        }
        .sheet(isPresented: $showSheet) {
            SheetContentView(showSheet: $showSheet)
        }
        
    }
}

先感谢您。

标签: swiftui

解决方案


当视图出现在视图层次结构中(而不是屏幕上)时,转换起作​​用,所以为了解决这个问题,我们需要另一个容器和状态。

这是一个固定的变体。使用 Xcode 12.1 / iOS 14.1 测试

演示

struct SheetContentView: View {
    @Binding var showSheet: Bool
    @State private var isShown = false
    var body: some View {
        VStack {            // container to animate transition !!
            if isShown {
                VStack(spacing: 8) {
                    Text("A great content of my new sheet")
                    Label("still not done", systemImage: "guitars")
                    Text("I'm done now")
                }
                .transition(.asymmetric(insertion: .scale, removal: .opacity))
            }
        }
        .animation(Animation.easeInOut(duration: 2))
        .onAppear {
            isShown = true       // << activate !!
        }
    }
}

推荐阅读