swift 如何在CoreData FetchedResults列表中实现onMove

utugiqy6  于 2023-03-28  发布在  Swift
关注(0)|答案(2)|浏览(138)

我有一个显示CoreData FetchedResults的List。我想实现移动行的可能性,同时更新实体的order属性。FetchedResults不是一个数组,所以我不能使用Array的move属性。这就是我如何实现的,但工作得不是很好。

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
        }
    }

在我的代码中,我得到一个当前顺序的数组,我执行移动,然后我重新分配它们。
我认为最好的选择是为Collection where Element: MyEntity, Index == Int创建一个自定义移动属性。
你知道吗?
要重新创建场景,您可以轻松地启动新的SwiftUI Master-Detail项目,并选择CoreData选项,然后只需将order属性添加到实体中(记住使用NSSortDescriptor(keyPath: \MyEntity.order, ascending: true)]@FetchRequest进行排序)

krcsximq

krcsximq1#

我发现它只需要一些调整:

///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]!
        }

}
ylamdve6

ylamdve62#

下面是我对@luomein的回答的解释,它提供了一种通用的方法来获得索引Map,使得move函数的实现简单得多。
首先,我们将这个扩展添加到Collection

extension Collection {
    func newIndices(moving source: IndexSet, to destination: Int) -> [Int: Int] {
        var oldIndexesByNewIndex: [Int] = Array(0..<self.count)
        oldIndexesByNewIndex.move(fromOffsets: source, toOffset: destination)
        return Dictionary(uniqueKeysWithValues:
                            oldIndexesByNewIndex.enumerated().map{ newIndex, oldIndex in (oldIndex, newIndex) }
        )
    }
    
}

然后我们这样使用它:

func move(from source: IndexSet, to destination: Int) {
        let newIndices = entities.newIndices(moving: source, to: destination)
        entities.enumerated().forEach { currentIndex, entity in
            if (newIndices[currentIndex] != currentIndex) {
                entity.order = newIndices[currentIndex]!
            }
        }
    }

相关问题