添加/删除行时,SwiftUI列出/形成不良动画

时间:2020-09-26 17:21:13

标签: swiftui swiftui-list swiftui-form

我有一个非常简单的文本列表,当用户点击它时,它的内部会带有一个日期选择器。

问题在于动画看上去真的很破损,除了从头开始做整个事情之外,不确定我能做些什么,在这一点上我宁愿只使用UIKit。

enter image description here

如果您知道如何解决此问题,我将非常感激。

这是代码:

struct ContentView: View {
    let items = ["123", "345", "678"]
    @State private var selectedItems = Set<String>()
    @State private var test = Date()

    var body: some View {
        Form {
            ForEach(items.indices) { index in
                Button(action: {
                    withAnimation {
                        if selectedItems.contains(items[index]) {
                            selectedItems.remove(items[index])
                        } else {
                            selectedItems.insert(items[index])
                        }
                    }
                }, label: {
                    Text(items[index])
                        .foregroundColor(.primary)
                })
                if selectedItems.contains(items[index]) {
                    DatePicker(selection: $test, in: ...Date(), displayedComponents: .date) {
                            }
                    .datePickerStyle(WheelDatePickerStyle())
                }
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

2 个答案:

答案 0 :(得分:2)

ForEach(content:)仅应用于静态集合。

如果您有一个 dynamic 集合(例如在您的示例中-您要添加/删除条目),则需要使用ForEach(id:content:)

ForEach(items.indices, id: \.self) { index in

请注意,如果您的馆藏中可能有重复的物品,那么id: \.self将无法正常工作,您可能需要创建一个符合Identifiable的结构。

答案 1 :(得分:1)

Section内使用ForEach

struct ContentView: View {
    let items = ["123", "345", "678"]
    @State private var selectedItems = Set<String>()
    @State private var test = Date()

    var body: some View {
        Form {
            ForEach(items.indices) { index in
                Section(header: header(index), content: {
                    if selectedItems.contains(items[index]) {
                        DatePicker(selection: $test, in: ...Date(), displayedComponents: .date) {
                                }
                        .datePickerStyle(WheelDatePickerStyle())
                    }
                })
            }
        }
    }
    
    private func header(_ index: Int) -> some View {
        Button(action: {
            withAnimation {
                if selectedItems.contains(items[index]) {
                    selectedItems.remove(items[index])
                } else {
                    selectedItems.insert(items[index])
                }
            }
        }, label: {
            Text(items[index])
                .foregroundColor(.primary)
        })
    }
}