SwiftUI - VStack 中的 ExpandableView

SwiftUI - ExpandableView inside VStack

我正在尝试在 VStack 中创建多个带有动画的可扩展视图。我有以下代码:

struct ContentView: View {
    var body: some View {
        NavigationView {
            ScrollView {
                VStack {
                    ExpandableView(headerTitle: "First")
                    ExpandableView(headerTitle: "Second")
                    Spacer()
                }
            }
        }
    }
}

以及 ExpandableView:

struct ExpandableView: View {
    let headerTitle: String
    @State private var collapsed: Bool = true
    
    var body: some View {
        Button(
            action: {
                self.collapsed.toggle()
            },
            label: {
                VStack(spacing: 2) {
                    ZStack {
                        Rectangle()
                            .fill(.gray)
                        VStack {
                            Text("\(headerTitle) Header")
                            if !collapsed {
                                HStack {
                                    Text("Text A")
                                    Text("Text B")
                                }
                            }
                        }
                    }
                    .frame(height: collapsed ? 52 : 80)
                    ZStack(alignment: .top) {
                        Rectangle()
                            .fill(.gray)
                            .frame(height: 204)
                        VStack {
                            Text("Content A")
                            Text("Content B")
                            Text("Content C")
                        }
                    }
                    .frame(maxHeight: collapsed ? 0 : .none)
                    .clipped()
                }
            }
        )
        .buttonStyle(PlainButtonStyle())
        .animation(.easeOut, value: collapsed)
    }
}

结果是这样的:

如您所见,我打开最后一个 expandableView 是否正确打开。但是,如果我在第二个关闭时打开第一个,它实际上会打开第二个。如果第二个已经打开,它只会正确打开第一个。似乎 VStack 本身没有正确呈现。任何想法为什么会这样? 感谢您的帮助。

我可能就是按钮的工作方式。这是一个更清洁的解决方案:

struct ExpandableView: View {
        let headerTitle: String
        @State private var collapsed: Bool = true
        
        var body: some View {
            
            VStack(spacing: 2) {
                
                Button(
                    action: {
                        withAnimation(.easeOut){
                            self.collapsed.toggle()
                        }
                    },
                    label: {
                        
                        VStack {
                            Text("\(headerTitle) Header")
                            if !collapsed {
                                HStack {
                                    Text("Text A")
                                    Text("Text B")
                                }
                            }
                        }.frame(maxWidth: .infinity)
                    })
                .buttonStyle(.borderedProminent)
                .tint(.gray)
                
                if(!self.collapsed) {
                    VStack {
                        Divider().background(.black)
                        Text("Content A")
                        Text("Content B")
                        Text("Content C")
                    }
                }
                Spacer()
            }
            .frame(height: collapsed ? 52 : 204)
            .frame(maxWidth: .infinity)
            .background(.gray)
            .padding()
        }
    }