SwiftUI 动画展开和折叠列表行

问题描述:

我正在使用 SwiftUI 为列表中的展开和折叠设置动画.

I'm using SwiftUI to animate an expand and collapse in a list.

如何让部分的高度扩展像在带有 tableview 的 UIKit 中一样平滑地动画?

How can I get the height expansion of the section to animate smoothly like it would in UIKit with a tableview?

struct Rows: View {
    let rows = ["Row 1", "Row 2", "Row 3", "Row 4", "Row 5"]

    var body: some View {
        Section {
            ForEach(rows.identified(by: \.self)) { name in
                Text(name)
                    .lineLimit(nil)
            }
        }
    }
}

struct Header: View {

    @State var isExpanded: Bool = false

    var body: some View {

        VStack(alignment: .leading) {
            Button(action: {
                self.isExpanded.toggle()

            }) {
                Text(self.isExpanded ? "Collapse Me" : "Expand Me")
                    .font(.footnote)
            }

            if self.isExpanded {
                Rows().animation(.fluidSpring())
            }
        }
    }
}

struct ContentView : View {

    var body: some View {
        List(0...4) { _ in
            Header()
        }
    }
}

动画似乎只适用于行中的文本,而不是实际高度或分隔线增长以容纳新行.行文本似乎也从行的最顶部开始动画,而不是它在视图层次结构中出现的位置.我需要流畅的动画.

The animation seems to only apply to the text in the rows not the actual height or separator line growing to accommodate the new rows. The row text also seems to start animating from the very top of the row rather than where it appears in the view hierarchy. I need a smooth animation.

我是这样实现的:(它有适当的动画)

I implemented it like this: (It is with proper animation)

struct ExpandCollapseList : View {
    @State var sectionState: [Int: Bool] = [:]

    var body: some View {
        NavigationView {
            List {
                ForEach(1 ... 6, id: \.self) { section in
                    Section(header: Text("Section \(section)").onTapGesture {
                        self.sectionState[section] = !self.isExpanded(section)
                    }) {
                        if self.isExpanded(section) {
                            ForEach(1 ... 4, id: \.self) { row in
                                Text("Row \(row)")
                            }
                        }
                    }
                }
            }
            .navigationBarTitle(Text("Expand/Collapse List"))
            .listStyle(GroupedListStyle())
        }
    }

    func isExpanded(_ section: Int) -> Bool {
        sectionState[section] ?? false
    }
}