I am trying to get the moveRowAtIndexPath
method to work using Core Data. My program is user-driven meaning that the user updates the data repeatedly and is basically a table view that displays the name of an Entity. Each Entity has two attributes: a name and an integer that represents its position in the tableView, let's call it orderPosition
. I have also created a local variable that stores the lastIndex
, which is the number of objects in my array. This allows me to assign an index value to each Entity that I create (last place in table). What I can't manage to figure out is how to use the stored attribute orderPosition
in my entity to create a sorted array for the tableView in my View Controller and how to use this to make moveRowAtIndexPath
work.
我正在尝试使用moveRowAtIndexPath方法来使用核心数据。我的程序是用户驱动的,意思是用户重复更新数据,基本上是显示实体名称的表视图。每个实体都有两个属性:一个名称和一个表示其在tableView中的位置的整数,我们称之为orderPosition。我还创建了一个本地变量来存储lastIndex,它是数组中对象的数量。这允许我为创建的每个实体(表中最后的位置)分配索引值。我搞不懂的是,如何使用实体中存储的属性orderPosition为我的视图控制器中的tableView创建一个排序数组,以及如何使用它使moveRowAtIndexPath工作。
override func viewWillAppear(animated: Bool) {
let appDelegate: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let context = appDelegate.managedObjectContext!
let fetchReq = NSFetchRequest(entityName: "Object")
objectData = context.executeFetchRequest(fetchReq, error: nil)!
lastIndex = objectData.count
tableView.reloadData()
}
override func tableView(tableView: UITableView, moveRowAtIndexPath sourceIndexPath: NSIndexPath, toIndexPath destinationIndexPath: NSIndexPath) {
let val: AnyObject = self.objectsData.removeAtIndex(sourceIndexPath.row)
self.objectsData.insert(val, atIndex: destinationIndexPath.row)
let appDelegate: AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let context = appDelegate.managedObjectContext!
var fetchReq = NSFetchRequest(entityName: "Object")
fetchReq.predicate = NSPredicate(format: "orderPosition = %@", sourceIndexPath.row)
if let fetchResults = appDelegate.managedObjectContext!.executeFetchRequest(fetchReq, error: nil) as? [NSManagedObject] {
if fetchResults.count != 0{
var managedObject = fetchResults[0]
managedObject.setValue(destinationIndexPath.row, forKey: "orderPosition")
context.save(nil)
}
}
}
2 个解决方案
#1
0
First, your array with a fetch requests necessary to retrieve the objects is not very efficient. Just use a NSFetchedResultsController
and the index paths will automatically point to your objects. In addition, you get great memory and performance optimizations for free.
首先,具有获取对象所需的fetch请求的数组不是非常有效。只要使用NSFetchedResultsController,索引路径就会自动指向你的对象。此外,您还可以获得巨大的内存和性能优化。
As has been pointed out in the comments, you need to save any new order. E.g. in viewWillDisappear
or just after re-ordering. Depending on your setup, it could be something similar to this:
正如评论中指出的,您需要保存任何新订单。在viewWillDisappear或刚重新订购之后。根据你的设置,它可能类似于:
for var i = 0; i < self.fetchedResultsController.fetchedObjects.count; i++ {
let indexPath = NSIndexPath(row:i section:0)
var object = self.fetchedResultsController.objectAtIndexPath(indexPath)
object.orderPosition = i+1
}
self.managedObjectContext.save(nil)
Make sure you add the sort descriptor to you fetched results controller. If you decide to dispense with the fetched results controller (not recommended) you have to include the sorting in the fetch request for populating your data array in viewDidLoad
.
确保向fetchedresultscontroller中添加了排序描述符。如果您决定不使用fetchedresultscontroller(不推荐),那么必须在fetch请求中包含排序,以便在viewDidLoad中填充数据数组。
#2
1
You can create a NSSortDescriptor to fetch the data:
您可以创建一个NSSortDescriptor来获取数据:
let sortDescriptor = NSSortDescriptor(key: "orderPosition", ascending: true)
let sortDescriptors = [sortDescriptor]
fetchReq.sortDescriptors = sortDescriptors
#1
0
First, your array with a fetch requests necessary to retrieve the objects is not very efficient. Just use a NSFetchedResultsController
and the index paths will automatically point to your objects. In addition, you get great memory and performance optimizations for free.
首先,具有获取对象所需的fetch请求的数组不是非常有效。只要使用NSFetchedResultsController,索引路径就会自动指向你的对象。此外,您还可以获得巨大的内存和性能优化。
As has been pointed out in the comments, you need to save any new order. E.g. in viewWillDisappear
or just after re-ordering. Depending on your setup, it could be something similar to this:
正如评论中指出的,您需要保存任何新订单。在viewWillDisappear或刚重新订购之后。根据你的设置,它可能类似于:
for var i = 0; i < self.fetchedResultsController.fetchedObjects.count; i++ {
let indexPath = NSIndexPath(row:i section:0)
var object = self.fetchedResultsController.objectAtIndexPath(indexPath)
object.orderPosition = i+1
}
self.managedObjectContext.save(nil)
Make sure you add the sort descriptor to you fetched results controller. If you decide to dispense with the fetched results controller (not recommended) you have to include the sorting in the fetch request for populating your data array in viewDidLoad
.
确保向fetchedresultscontroller中添加了排序描述符。如果您决定不使用fetchedresultscontroller(不推荐),那么必须在fetch请求中包含排序,以便在viewDidLoad中填充数据数组。
#2
1
You can create a NSSortDescriptor to fetch the data:
您可以创建一个NSSortDescriptor来获取数据:
let sortDescriptor = NSSortDescriptor(key: "orderPosition", ascending: true)
let sortDescriptors = [sortDescriptor]
fetchReq.sortDescriptors = sortDescriptors