在CoreData中重新排序UITableViewCells和对象

时间:2016-07-23 04:55:03

标签: sorting core-data nsfetchedresultscontroller nsmanagedobject

我在应用中使用Core Data。我有UITableView并且正在使用NSFetchedResultsController

这些是我的实体和属性:

Entities

我的设置如下:

    let fetchRequest = NSFetchRequest(entityName: "Timer")
    let fetchSort = NSSortDescriptor(key: "orderBy", ascending: true)
    let predicate = NSPredicate(format: "%K == %@", "timerWorkout", workout)
    fetchRequest.predicate = predicate
    fetchRequest.sortDescriptors = [fetchSort]

    fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
    fetchedResultsController.delegate = self

    do {
        try fetchedResultsController.performFetch()
    }
    catch let error as NSError {
        print("Unable to perform fetch: \(error.localizedDescription)")
    }

我有锻炼项目,上面有计时器列表。用户可以添加计时器,我希望他们能够以他们想要的任何方式订购它们。为了可以指定订单,我添加了orderBy属性。添加新项目时,我使用此代码确定orderBy的值:

    if let timer = vc?.timer {
        timer.orderBy = workout.workoutTimers?.count
        workout.mutableSetValueForKey("workoutTimers").addObject(timer)

        do {
            try context.save()
        }
        catch {
            print("Unable to add timer.")
        }
    }

它适用于它的本质。我遇到的问题是我想通过允许用户在列表中移动它来重新排序项目。移动UITableViewCell项很容易,但我无法弄清楚如何在数据集中重新排序它们。这是我尝试过的一些内容。注释掉的行是我尝试过的各种各样的东西。

func tableView(tableView: UITableView, moveRowAtIndexPath sourceIndexPath: NSIndexPath, toIndexPath destinationIndexPath: NSIndexPath) {

    //let orderedSet = workout.valueForKey("workoutTimers") as? NSMutableOrderedSet
    //myObject.valueForKeyPath("subObjects") as NSMutableSet
    //let orderedSet = fetchedResultsController.mutableCopy() as! NSMutableOrderedSet
    //let orderedSet: NSMutableOrderedSet = (fetchedResultsController?.mutableOrderedSetValueForKey("Timer"))!
    //let orderedSet: NSMutableOrderedSet = (workout.mutableOrderedSetValueForKey("workoutTimers"))
    //let orderedSet = workout.mutableOrderedSetValueForKey("workoutTimers")
    let orderedSet = workout.workoutTimers?.mutableOrderedSetValueForKey("orderBy")
    orderedSet.exchangeObjectAtIndex(sourceIndexPath.row, withObjectAtIndex: destinationIndexPath.row)

    do {
        try context.save()
    }
    catch {
        print("Unable to reorder.")
    }
}

到目前为止,没有任何作用。我主要得到的例外是: 这个类不是密钥的密钥值编码兼容。

任何人都可以提供一些我对此缺失的帮助吗?

编辑:

在阅读了关于这个问题的评论之后,这就是我想出来的。它似乎有效,而且更清洁。

func tableView(tableView: UITableView, moveRowAtIndexPath sourceIndexPath: NSIndexPath, toIndexPath destinationIndexPath: NSIndexPath) {
    if let items: NSMutableArray = NSMutableArray(array: fetchedResultsController.fetchedObjects!) {
        if let sourceItem = items.objectAtIndex(sourceIndexPath.row) as? Timer {
            items.removeObject(sourceItem)
            items.insertObject(sourceItem, atIndex: destinationIndexPath.row)

            var index = 0

            for item in items {
                (item as? Timer)?.orderBy = index
                index += 1
            }

            do {
                try context.save()
            }
            catch {
                print("Unable to reorder.")
            }

            timersTable.reloadData()
        }
    }
}

1 个答案:

答案 0 :(得分:0)

真的,你不应该尝试对有序关系做任何事情。您应该在项目移动的索引上创建一个循环,并添加和减去以重新组织值。因此,移动的项目会增加或减少移动的大小,其他所有内容都会添加或减去。