重新排序 CoreData 中的 UITableViewCells 和对象

Posted

技术标签:

【中文标题】重新排序 CoreData 中的 UITableViewCells 和对象【英文标题】:Reorder UITableViewCells and objects in CoreData 【发布时间】:2016-07-23 04:55:02 【问题描述】:

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

这些是我的实体和属性:

我的设置如下所示:

    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.")
    

到目前为止,没有任何效果。我主要得到的例外是: 此类与键的键值编码不兼容。

任何人都可以就我所缺少的内容提供一些帮助吗?

编辑:

在阅读了有关该问题的 cmets 之后,这就是我想出的。它似乎有效,而且更干净。

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】:

真的,您不应该尝试对有序关系进行任何操作。您应该在项目移动的索引上创建一个循环,并添加和减去以重新组织值。因此,被移动的项目的大小与移动的大小相同或被减去,而其他所有项目的大小都被添加或减去。

【讨论】:

我想我明白你在说什么。我用似乎可以正常工作的解决方案更新了我的问题。

以上是关于重新排序 CoreData 中的 UITableViewCells 和对象的主要内容,如果未能解决你的问题,请参考以下文章

如何更改coredata中的记录顺序?

使用 Fetch Results Controller 对 Core Data 中的单元格重新排序

重新排序 TableView 时如何更改 CoreData 的索引?

在 CoreData 中使用 NSOrderedSet 重新排序 UITableView

Core Data 数据模型中的订单实体

使用 Core Data 时如何重新排列部分