SwiftUI 如何使用滑动禁用行删除?

cap*_*ara 3 swiftui

我在 SwiftUI 中使用 Xcode 11.1。

我使用以下代码实现了列表删除和排序功能。

如何使用滑动禁用行删除?

import SwiftUI

struct ContentView: View {
    @State var fruits = ["Apple",  "Orange",  "Banana"]

    var body: some View {
        NavigationView {
            List {
                ForEach(fruits, id: \.self) { fruit in
                    Text(fruit)
                }
                .onMove(perform: move)
                .onDelete(perform: delete)
            }
            .navigationBarItems(trailing: EditButton())
        }
    }

    func delete(offsets: IndexSet) {
        fruits.remove(atOffsets: offsets)
    }

    func move(source: IndexSet, destination: Int) {
        fruits.move(fromOffsets: source, toOffset: destination)
    }
}
Run Code Online (Sandbox Code Playgroud)

MrA*_*zaa 10

您可以使用.deleteDisabled(_ isDisabled:)修饰符。但是你必须考虑到这个修饰符的返回类型是View,不是Text。所以它实现起来有点复杂。您可以使用此示例:

  1. 创建一个CellView这样的:
struct CellView: View {
    var title: String
    var isDeletable: Bool

    var body: some View {
        return Text(title).deleteDisabled(!isDeletable)
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以使用VStacks、HStacks 等来设计您的单元格,但您应该考虑在此层次结构的父级上使用此修饰符。如下图所示:

var body: some View {
    HStack {
        VStack {
            ZStack {
                ...
            }
        }
    }
    .deleteDisabled(!isDeletable)
}
Run Code Online (Sandbox Code Playgroud)
  1. 之后,您可以ForEach像下面这样使用它:
struct ContentView: View {
    @State var fruits = ["Apple",  "Orange",  "Banana"]

    var body: some View {
        NavigationView {
            List {
                ForEach(fruits, id: \.self) { fruit -> CellView in
                    if fruit == "Orange" {
                        return CellView(title: fruit, isDeletable: true)
                    } else {
                        return CellView(title: fruit, isDeletable: false)
                    }
                }
                .onMove(perform: move)
                .onDelete(perform: delete)
            }
            .navigationBarItems(trailing: EditButton())
        }
    }

    func delete(offsets: IndexSet) {
        fruits.remove(atOffsets: offsets)
    }

    func move(source: IndexSet, destination: Int) {
        fruits.move(fromOffsets: source, toOffset: destination)
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @capibara您可以添加`@Environment(\.editMode) var mode`来观察编辑模式。然后您可以像这样访问其包装值:`self.mode?.wrappedValue` 然后您可以使用条件决定是否显示可删除单元格或不显示可删除单元格。 (3认同)