SwiftUI 在 iOS 15 上使用 editMode 的 onDelete 修饰符以及自定义滑动操作

Ada*_*ift 8 editmode ios swiftui swiftui-swipeactions

初始描述

我目前有一个动态列表,我正在使用 SwiftUI 内置editMode功能和内置功能EditButton(),以便让用户从列表中删除项目。

对于删除部分,我使用的onDelete修改器添加了尾随的红色删除滑动手势,就像现在一样。

这是一个例子:

List {
    ForEach(someList) { someElement in
        Text(someElement.name)
    }
    .onDelete { (indexSet) in }
    .onMove { (source, destination) in }
}
.toolbar {
    ToolbarItem(placement: .navigationBarLeading) {
        EditButton()
    }
}
.environment(\.editMode, $editMode)
Run Code Online (Sandbox Code Playgroud)

目标

现在我还想使用 iOS 15.swipeActions修改器,它允许添加我们自己的自定义前导或尾随滑动手势。

我希望用户也能够通过向右滑动来编辑列表元素,因此我在行中添加了一个前导滑动操作:

Text(someElement.name)
.swipeActions(edge: .leading) {
    Button("Edit") { }
}
Run Code Online (Sandbox Code Playgroud)

按钮操作显然会包含允许编辑的代码。

问题

使用.swipeActions修饰符会破坏 的正常行为editMode,尤其是.onDelete修饰符。事实上,通过这种设置,我无法再向左滑动来删除该行。

所以问题是:如何在列表上使用 SwiftUIeditMode.onDelete修饰符以及我自己的自定义leading滑动操作?

最小可重复示例

Xcode 游乐场,适用于 iOS 15。

import SwiftUI
import PlaygroundSupport

struct SomeList: Identifiable {
    let id: UUID = UUID()
    var name: String
}

let someList: [SomeList] = [
    SomeList(name: "row1"),
    SomeList(name: "row2"),
    SomeList(name: "row3")
]

struct ContentView: View {
    @State private var editMode = EditMode.inactive
    
    var body: some View {
        NavigationView {
            List {
                ForEach(someList) { someElement in
                    Text(someElement.name)
                    .swipeActions(edge: .leading) {
                        Button("Edit") { }
                    }
                }
                .onDelete { (indexSet) in }
                .onMove { (source, destination) in }
            }
            .toolbar {
                ToolbarItem(placement: .navigationBarLeading) {
                    EditButton()
                }
            }
            .environment(\.editMode, $editMode)
        }
    }
}

PlaygroundPage.current.setLiveView(ContentView())
Run Code Online (Sandbox Code Playgroud)

您可以测试以下内容:如果您评论或删除这部分:

.swipeActions(edge: .leading) {
    Button("Edit") { }
}
Run Code Online (Sandbox Code Playgroud)

然后.onDelete修改器再次起作用。将其重新打开会破坏该.onDelete功能。

附加信息

我正在为iOS 15构建这个应用程序,因为我使用了.swipeActions修改器。

我愿意接受任何能够实现我的目标的解决方案,即让用户向左滑动以删除行并向右滑动以触发任何版本代码。即使这意味着使用修饰符的另一种方式,或SwiftUI 修饰符的.swipeActions另一种方式,或两者兼而有之。.onDeleteeditMode

我不得不为 iOS 15 构建应用程序只是因为这个.swipeActions修饰符,所以如果我可以为较低的 iOS 版本构建应用程序那就更好了。

如果您需要任何其他信息,请立即联系我。谢谢。

Leg*_*ang 0

这就是您想要删除特定行的操作。您可以在swipeAction(), 以及.onDelete()

它可以让您保持它们的功能。

func deleteSelectedItem(selectedItem: FetchedResults<Item>.Element) {
    viewContext.delete(selectedItem as NSManagedObject)
    saveCoreData()
}
Run Code Online (Sandbox Code Playgroud)

就像使用它一样

ForEach(items) { item in
Text("").swipeActions() { Button { deleteSelectedItem(selectedItem: item) } }
Run Code Online (Sandbox Code Playgroud)

并且它将删除触发滑动的项目。之后,您还可以将原始内容添加到onDelete()外部ForEach

 ForEach {    } .onDelete(perform: deleteItems)
Run Code Online (Sandbox Code Playgroud)

他们都会为你工作。