【问题标题】:SwiftUI List/Form bad animation when adding/removing rows添加/删除行时,SwiftUI List/Form 动画效果不佳
【发布时间】:2020-09-26 17:21:13
【问题描述】:

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

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

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

代码如下:

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()
    }
}

【问题讨论】:

标签: swiftui swiftui-list swiftui-form


【解决方案1】:

ForEach(content:) 只能用于 static 集合。

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

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

请注意,如果您的集合可能有重复项,则id: \.self 将无法正常工作,您可能需要创建一个符合Identifiable 的结构。

【讨论】:

  • 更改为 ForEach(items.indices, id: \.self) { index in 对动画故障没有影响 =/
【解决方案2】:

ForEach 中使用Section

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)
        })
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-04
    • 1970-01-01
    • 2020-06-14
    • 1970-01-01
    • 2019-04-12
    • 1970-01-01
    相关资源
    最近更新 更多