How can I implement onMove in a List of CoreData FetchedResults

Viewed 682

I have a List showing CoreData FetchedResults. I would like to implement the possibility to move row and at the same time update the order attribute of the entity. FetchedResults is not an array so I cannot use the move property of Array. This is how I've implemented this but is not working very well.

func move(fromOffsets: IndexSet, toOffset: Int) {
        var orders: [Int16] = Array(1...Int16(myEntities.count))
        orders.move(fromOffsets: fromOffsets, toOffset: toOffset)
        for (entity, order) in zip(myEntities, orders) {
            entity.order = order
        }
    }

In my code I get an array of the current order, I perform the move and then I reassign them.

I think the best option would be to create a custom move property for Collection where Element: MyEntity, Index == Int.

Any idea?

To recreate scenario you can easily start new SwiftUI Master-Detail project with CoreData option selected, then just add the order attribute to the entity (Remember to sort the @FetchRequest with NSSortDescriptor(keyPath: \MyEntity.order, ascending: true)])

1 Answers

I find it just needs some tweaking:

///example: source = 1, destination = 4
///original list: [a,b,c,d,e]
///final list: [b,c,d,a,e]
func move(from source: IndexSet, to destination: Int)
         var sortedOrders: [Int16] = Array(1...Int16(myEntities.count))
        for (entity, order) in zip(myEntities, sortedOrders) {
            entity.order = order
        }
        
        sortedOrders.move(fromOffsets: source, toOffset: destination)
        var finalOrders : [Int16] = Array(1...Int16(myEntities.count))
        var mappingDict = Dictionary(uniqueKeysWithValues: zip(sortedOrders , finalOrders ) )
        // [5: 5, 4: 3, 2: 1, 1: 4, 3: 2]
        
        for entity in myEntities{
            entity.order = mappingDict[entity.order]!
        }

}
Related