I’m trying to get a drag an droppable horizontal list in cell view of a main list which vertical.
here is my solution. it doesnt work inside a cell view of a list view but it works outside of List{}. how to get a horizontal list to be drag and droppable for rearranging cells inside a cell of a Vertical List{}?
this is the main list view which show some cells with sections. i removed all other except the one with a cell containg horizontal list with drag and droppable of this sub list.
import SwiftUI
struct ChipModel : Codable, Identifiable, Equatable, Hashable {
let id : UUID
var isSelected : Bool
var titleKey : String
var systemImage : String
}
struct AppView : View {
var myList = [ChipModel(id: UUID(), isSelected: false, titleKey: "Year", systemImage: ""),
ChipModel(id: UUID(), isSelected: false, titleKey: "Month", systemImage: ""),
ChipModel(id: UUID(), isSelected: false, titleKey: "Day", systemImage: "")]
var body: some View {
VStack {
NavigationView {
List {
Section(header: Text("doc")) {
HStack {
ChipView(chips: myList)
}
}
}
}
}
}
}
here is the chipview
import Foundation
import SwiftUI
import UniformTypeIdentifiers
struct ChipView : View {
@State var chips : [ChipModel]
@State var draggedItem: ChipModel?
var body: some View {
LazyHStack(spacing : 5) {
ForEach(chips, id:\.id.uuidString) { item in
Text(item.titleKey)
.frame(minWidth:0, maxWidth:.infinity, minHeight:50)
.border(Color.black).background(Color.red)
.onDrag({
self.draggedItem = item
return NSItemProvider(item: nil, typeIdentifier: item.id.uuidString)
}) .onDrop(of: [UTType.text], delegate: MyDropDelegate(item: item, items: $chips, draggedItem: $draggedItem))
}
}
}
}
struct MyDropDelegate : DropDelegate {
let item : ChipModel
@Binding var items : [ChipModel]
@Binding var draggedItem : ChipModel?
func performDrop(info: DropInfo) -> Bool {
return true
}
func dropEntered(info: DropInfo) {
guard let draggedItem = self.draggedItem else {
return
}
if draggedItem != item {
let from = items.firstIndex(of: draggedItem)!
let to = items.firstIndex(of: item)!
withAnimation(.default) {
self.items.move(fromOffsets: IndexSet(integer: from), toOffset: to > from ? to + 1 : to)
}
}
}
}