使用 NSFetchedResultsController 核心数据重新排序 TableView 单元格 - Swift 3

Dev*_*ace 6 core-data uitableview ios swift swift3

我正在使用 NSFetchedResultsController。我找不到任何简单的教程来遍历它Swift 3

所以这是我到目前为止所做的。我已经使用NSFetchedResultsController从核心数据中获取插入数据的成功填充了我的表。我在我的核心数据模型中创建了一个名为的属性,该属性orderPosition声明为Int32. 关于在插入时将数据添加和保存到核心数据,我没有对这个属性做任何事情。

在我func初始化 的fetch中NSFetchedResultsController,我修改了我的排序描述符以包含以下代码:

let sortDescriptor = NSSortDescriptor(key: "orderPosition", ascending: true)
fetchRequest.sortDescriptors = [sortDescriptor]
Run Code Online (Sandbox Code Playgroud)

然后我实现了tableViewfunc:

func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {

    attemptFetch()
    var objects = self.controller.fetchedObjects! 
    self.controller.delegate = nil

    let object = objects[sourceIndexPath.row]
    objects.remove(at: sourceIndexPath.row)
    objects.insert(object, at: destinationIndexPath.row)

    var i = 0
    for object in objects {
        object.setValue(i += 1, forKey: "orderPosition")
    }

    appdel.saveContext()
    self.controller.delegate = self

}
Run Code Online (Sandbox Code Playgroud)

在我执行的didChangeanObject FUNC,我包括开关情况下.insert.delete.update,和.move。我的.move情况如下所示:

case.move:
        if let indexPath = indexPath {
            tableView.deleteRows(at: [indexPath], with: .fade)
        }
        if let indexPath = newIndexPath {
            tableView.insertRows(at: [indexPath], with: .fade)
        }
        break
Run Code Online (Sandbox Code Playgroud)

请帮我解决这个问题。我花了数周时间试图理解这一点。我已经解决了很多(如果不是全部)堆栈溢出问题。我从一个实现了一些循环的想法,因为我有一个类似的思考过程来解决这个问题,但它没有奏效。没有我遇到的 Swift 3 核心数据教程/视频可以真正帮助我解决和理解这个问题。我不想放弃这个。

Ale*_*kov 5

刚刚在我的项目中实现了类似的功能。结果比看起来更容易。

这是您的moveRowAt方法的更新

func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {

    // NOT NEEDED, SINCE I ASSUME THAT YOU ALREADY FETCHED ON INITIAL LOAD
    // attemptFetch()

    var objects = self.controller.fetchedObjects! 

    // NOT NEEDED
    //self.controller.delegate = nil

    let object = objects[sourceIndexPath.row]
    objects.remove(at: sourceIndexPath.row)
    objects.insert(object, at: destinationIndexPath.row)

    // REWRITEN BELOW
    //var i = 0
    //for object in objects {
    //    object.setValue(i += 1, forKey: "orderPosition")
    //}

    for (index, item) in items.enumerated() {
        item.orderPosition = index
    }

    appdel.saveContext()
    //self.controller.delegate = self

}
Run Code Online (Sandbox Code Playgroud)

didChange技术上讲,您不需要任何代码。当您在其中移动项目时,该表将就地更新。保存上下文时,会更新 coreData 中的数据。因此,下次获取数据时,根据您拥有的 sortDescriptor,它将按 orderPosition 排序。

为我工作。如果您有任何问题,请告诉我。


Jon*_*ose 3

Swift 与 C 的不同之处在于 =、+= 和其他类似赋值的操作返回Void。因此,您的行将object.setValue(i += 1, forKey: "orderPosition")设置i为 1,但始终将位置设置为 0。尝试改为:

var i = 0
for object in objects {
    i += 1
    object.setValue(i, forKey: "orderPosition")
}
Run Code Online (Sandbox Code Playgroud)

或者如果你想简化你的代码,你可以这样做

for (i, object) in objects.enumerated() {
    object.setValue(i, forKey: "orderPosition")
}
Run Code Online (Sandbox Code Playgroud)