我目前正在SwiftUI中构建一个SwiftUI列表应用程序。我真正想要实现的一个特性是手动排序列表的能力,因此我已经在填充我的.onMove循环中使用ForEach修饰符集成了该功能,但仍然必须手动切换EditMode,因此我将列表的EditMode设置为.active,如下所示:
import SwiftUI
struct ContentView: View {
@State private var items = ["1", "2", "3"]
@State var editMode: EditMode = .active
var body: some View {
List {
ForEach(items, id: \.self) { item in
Text("Item \(item)")
}
.onMove(perform: { _, _ in })
}
.environment(\.editMode, $editMode)
}
}但是我对这个实现并不满意,因为我仍然需要使用来自EditMode的抓地力,它还破坏了SwipeActions和Button的功能。
那么,如何在不使用EditMode的情况下移动列表项呢?
发布于 2021-11-24 13:26:10
根据Asperi对this问题的回答,我实现了拖拽手势来解决这个问题,如下所示:
struct ContentView: View {
@State var items = [Item(id: 1), Item(id: 2), Item(id: 3), Item(id: 4)]
@State private var dragging: Item?
var body: some View{
List{
ForEach(items){ item in
Text("Item \(item.id)")
.onDrag {
self.dragging = item
return NSItemProvider(object: NSString())
}
.onDrop(of: [UTType.text], delegate: DragDelegate(current: $dragging))
}
.onMove(perform: {_, _ in })
}
}
}使用DropDelegate实现:
struct DragDelegate<Item: Equatable>: DropDelegate {
@Binding var current: Item?
func dropUpdated(info: DropInfo) -> DropProposal? {
DropProposal(operation: .move)
}
func performDrop(info: DropInfo) -> Bool {
current = nil
return true
}
}注意:这些项目现在必须符合Identifiable & Equatable,所以最小的实现是:
struct Item: Identifiable, Equatable{
let id: Int
}你还需要进口:
import UniformTypeIdentifiers为了使用拖放功能
https://stackoverflow.com/questions/70069484
复制相似问题