删除项目后不需要的列表项目缩进 SwiftUI 列表

Unwanted list item indent SwiftUI List after deleting items

从列表中删除所有项目然后将项目添加回列表后,每个列表项目都缩进,就像在编辑模式下一样,并且滑动操作不可用。我只有在条件检查数组是否为空时才看到问题。

struct TestView: View {
    @State var categories = ["dog", "cat"]

    var body: some View {
        VStack {
            if(categories.isEmpty){
                Button ("Add category"){
                    categories = ["dog", "cat"]
                }
            } else {
                List {
                    ForEach(categories.indices, id: \.self) { i in
                        Text(categories[i])
                            .swipeActions(allowsFullSwipe: false) {
                                Button(role: .destructive) {
                                    categories.remove(at: i)
                                } label: {
                                    Label("Delete", systemImage: "trash.fill")
                                }
                            }
                    }
                }
            }
        }
    }
}

从数组中删除项目之前:

删除项目并将新项目添加到数组后:

这里有一个例子,说明删除不是问题

struct TestView: View {
    @State var categories = ["dog", "cat"]

    var body: some View {
        VStack {
            if(categories.isEmpty){
                Button ("Add category"){
                    categories = ["dog", "cat"]
                }
            } else {
                List {
                    ForEach(categories.indices, id: \.self) { i in
                        Text(categories[i])
//                            .swipeActions(allowsFullSwipe: false) {
//                                Button(role: .destructive) {
//                                    categories.remove(at: i)
//                                } label: {
//                                    Label("Delete", systemImage: "trash.fill")
//                                }
//                            }
                        .onTapGesture {
                            categories.remove(at: i)
                        }
                    }
                }
            }
        }
    }}

问题是,在使用 swipeActions 从列表中删除一个元素后,列表应该重新定位自己,在使用 swipeActions 从列表中删除最后一个元素后这样做,你决定让列表消失,这样它就不会是时候完成他的动作了。

我建议使用以下代码,效果很好

struct TestView: View {
    @State var categories = ["dog", "cat"]


    var body: some View {
        VStack {
            if(categories.isEmpty){
                Button ("Add category"){
                    categories = ["dog", "cat"]
                }
            }
            List {
                ForEach(categories.indices, id: \.self) { i in
                    Text(categories[i])
                    .swipeActions(allowsFullSwipe: false) {
                         Button(role: .destructive) {
                             categories.remove(at: i)
                         } label: {
                             Label("Delete", systemImage: "trash.fill")
                         }
                    }
                }
            }
             // don't display if categories.isEmpty
            .frame(height: categories.isEmpty ? 0 : nil)
        }
    }}

这是一个可能的解决方案。您可以尝试为此使用 onDelete,文档为 here。如果需要,我还包括 onMove 并添加了一个按钮,该按钮仅在数组为空时才处于活动状态。

struct ContentView: View {
    @State private var animals = [
        "Dog",
        "Cat",
    ]
    
    var body: some View {
        NavigationView {
            List {
                ForEach(animals, id: \.self) { animal in
                    Text(animal)
                }
                .onDelete { self.delete(at :[=10=]) }
                .onMove { self.move(from: [=10=], to: ) }
            }
            .navigationTitle("Animals")
            .toolbar {
                ToolbarItem(placement: .navigationBarLeading) {
                    Button(action: {
                        self.animals = [
                            "Dog",
                            "Cat",
                        ]
                    }, label: {
                        Label("Add", systemImage: "plus")
                            .labelStyle(.iconOnly)
                    }).disabled(!animals.isEmpty)
                }
                ToolbarItem(placement: .navigationBarTrailing) {
                    EditButton()
                }
            }
        }
    }
    
    func delete(at: IndexSet) {
        for i in at {
            animals.remove(at: i)
        }
    }
    
    func move(from: IndexSet, to: Int) {
        animals.move(fromOffsets: from, toOffset: to)
    }
}