我正在尝试使用核心数据和nsfetchresultscontroller重新排序表视图中的单元格。我找到了一些方法,使用目标C(其中我什么都不知道)这样做,并尝试在swift中实现它们,这是我想出的:
var books: Array<AnyObject> = []
// Override to support rearranging the table view.
override func tableView(tableView: UITableView, moveRowAtIndexPath fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath) {
books = fetchedResultsController.fetchedObjects!
let book = fetchedResultsController.objectAtIndexPath(fromIndexPath)
self.fetchedResultsController.delegate = nil
books.removeAtIndex(fromIndexPath.row)
books.insert(book, atIndex: toIndexPath.row)
var i = 0
for book in books {
book.setValue(i++, forKey: "position")
}
try! context.save()
self.fetchedResultsController.delegate = self
}
委托和上下文引用位于另一个文件的扩展名中。 使用此代码有时它可以工作,有时它不会。我改变了顺序,再次运行应用程序,这是一个完全不同的顺序,我无法弄清楚。特别是当我一次移动多行时。如果我将每个对象的“位置”属性打印到控制台,我可以看到它们确实没有正确更新。但为什么不呢?
我做错了什么?什么是更好的选择?
提前致谢,
丹尼尔
编辑:
好的,这是工作代码:
func initializeFetchedResultsController() {
let request = NSFetchRequest(entityName: "Book")
let sortDescriptor = NSSortDescriptor(key: "position", ascending: true)
request.sortDescriptors = [sortDescriptor]
self.fetchedResultsController = NSFetchedResultsController(fetchRequest: request, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
self.fetchedResultsController.delegate = self
do {
try self.fetchedResultsController.performFetch()
} catch {
fatalError("Failed to initialize FetchedResultsController: \(error)")
}
}
// Override to support rearranging the table view.
override func tableView(tableView: UITableView, moveRowAtIndexPath fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath) {
initializeFetchedResultsController()
var objects = self.fetchedResultsController.fetchedObjects! as! [ObjectClass]
self.fetchedResultsController.delegate = nil
let object = objects[fromIndexPath.row]
objects.removeAtIndex(fromIndexPath.row)
objects.insert(object, atIndex: toIndexPath.row)
var i = 0
for object in objects {
object.position = i++
}
try! context.save()
self.fetchedResultsController.delegate = self
}
诀窍是initializeFetchedResultsController函数,除了在viewDidLoad,我有它,必须在moveRowAtIndexPath位内重复。此外,初始化函数和数组声明必须在将FRC委托设置为nil之前(显然,但很容易错过)。
答案 0 :(得分:4)
您不应该编辑books
,它不属于您,并且实际上是私人数据。相反,您应该只更新正在移动的对象以更改position
值。如果使用当前逻辑中的数组重新排序来执行此操作,则应创建FRC提供的阵列的新可变副本。您还应该将位置的新值设置为NSNumber
个实例。
答案 1 :(得分:0)
您需要使用sortDescriptor,然后从获取请求中获取的信息已经排序。这就是我实现fetchRequests的方法:
lazy var connectionsFetchRequest: NSFetchRequest = {
var request = NSFetchRequest(entityName: "Connection")
let predicate = NSPredicate(format: "%K == %@", argumentArray: ["user", UserManager.SharedInstance.user!])
request.sortDescriptors = [NSSortDescriptor(key: "firstName", ascending: true)]
request.predicate = predicate
return request
}()