在下面的代码中,我试图实现从列表部分到另一个列表部分的移动(拖动)。
我有一个包含 5 个元素的枚举和一个包含这些枚举数组的状态变量 (activeElements)。 在视图中有一个包含 2 个部分的列表:
在第 1 节中,我应该能够四处移动元素,也可以将元素拖到第 2 节的所需位置。 在第 2 节中,我应该能够将元素拖到第 1 节中,我不关心本节中的移动元素。
第 1 节完美无缺。我的问题是我无法从 section2 拖动到 section1。我只能从第 2 部分拖到第 2 部分(加号绿点只出现在那里)。 如果我将 onMove 添加到第 2 部分,我将失去从第 1 部分到第 2 部分的拖动。这些部分将仅在其中移动元素。
你对如何实现从一个部分到另一个部分的移动有什么建议吗?或者也许我可以如何在同一部分的 2 个 foreach 之间移动元素。
代码如下:
enum RandomElements: Int, CaseIterable {
case element1 = 1
case element2 = 2
case element3 = 3
case element4 = 4
case element5 = 5
}
extension RandomElements {
var string: String {
switch self {
case .element1:
return "element1"
case .element2:
return "element2"
case .element3:
return "element3"
case .element4:
return "element4"
case .element5:
return "element5"
}
}
}
struct TwoSections: View {
@State var activeElements: [RandomElements] = []
@State var listMode: EditMode = .inactive
var body: some View {
List {
Section(header: Text("Active elements")) {
ForEach(activeElements, id: \.self) { elem in
HStack {
Text(elem.string)
Spacer()
Image(systemName: "minus")
.onTapGesture { activeElements.remove(at: activeElements.firstIndex(of: elem)!) }
}
.onDrag { NSItemProvider(object: String(elem.rawValue) as NSString ) }
}
.onInsert(of: [.plainText], perform: dropToSection1)
.onMove { (indexSet, index) in
activeElements.move(fromOffsets: indexSet, toOffset: index)
}
}
Section(header: Text("Available elements")) {
ForEach(RandomElements.allCases, id: \.self) { elem in
if !activeElements.contains(elem) {
HStack {
Text(elem.string)
Spacer()
Image(systemName: "plus")
.onTapGesture { activeElements.append(elem) }
}
.onDrag { NSItemProvider(object: String(elem.rawValue) as NSString ) }
}
}
.onInsert(of: [.plainText], perform: dropToSection2)
// .onMove { (indexSet, index) in
// }
}
}
.toolbar {
EditButton()
}
.environment(\.editMode, .constant(.active))
}
private func dropToSection1(at index: Int, _ items: [NSItemProvider]) {
for item in items {
_ = item.loadObject(ofClass: String.self) { droppedString, _ in
if let statusType = Int(droppedString ?? "") {
activeElements.remove(at: activeElements.firstIndex(of: RandomElements(rawValue: statusType)!)!)
}
}
}
}
private func dropToSection2(at index: Int, _ items: [NSItemProvider]) {
for item in items {
_ = item.loadObject(ofClass: String.self) { droppedString, _ in
if let statusType = Int(droppedString ?? "") {
print("append \(RandomElements(rawValue: statusType)!)")
activeElements.insert(RandomElements(rawValue: statusType)!, at: index)
}
}
}
}
}
诀窍是只使用一个 ForEach。您不能在不同的“ForEach”块之间移动项目。
这对我有用:
List {
ForEach(0 ..< 10) { i in
Section {
Text(String(i))
} header: {
if(i==0) {
Text("First Header")
}
if(i==5) {
Text("Second Header")
}
}
}
.onMove(perform: move)
.onDelete(perform: delete)
}
从标题块返回任何内容以对您的项目进行分组。