iOS:NSFetchResultsController对瞬态属性的排序(Swift)

时间:2014-12-07 20:03:03

标签: ios sorting core-data swift transient

比如说我有Entity名为任务,其中Attribute名为日期,而UITableView填充此任务 Entity

这是我目前看到的:

7-Dec-14 09:30
7-Dec-14 11:00
7-Dec-14 13:30
7-Dec-14 16:00

现在让我们假装当前时间实际上是7月12日 - 12月12日,所以前两行已经过去了,但是后两行是将来的。我想将这些内容拆分为UITableView

中的群组

我发现我可以在实体上创建一个瞬态属性,如下所示:

var dateGroup: NSNumber {
    get {
        if date.compare(NSDate()) == NSComparisonResult.OrderedAscending {
            return 0
        } else {
            return 1
        }
    }
}

当我设置sectionNameKeyPath:“dateGroup”时,现在显示UITableView,如下所示:

Group 0
7-Dec-14 09:30
7-Dec-14 11:00
Group 1
7-Dec-14 13:30
7-Dec-14 16:00

我的麻烦是如何让UITableView实际显示这样的结果(以便将来的任务超过过期的任务):

Group 1
7-Dec-14 13:30
7-Dec-14 16:00
Group 0
7-Dec-14 09:30
7-Dec-14 11:00

我尝试在瞬态属性(dateGroup)上创建NSSortDescriptor,但这不起作用。

我意识到这种情况正在发生,因为{date}属性上的NSSortDescriptor。但我不知道如何搜索日期>的行。 currentDate,后跟日期<的currentdate。

我认为基本上我想要做的是交换IF周围的部分超过1。

希望这是有道理的。你会如何解决这个排序问题?

更新

好的,我已经完全重写它以使用2 x FetchRequestControllers self.upcomingFRC(第0部分)和self.elapsedFRC(第1部分),现在以下工作没有任何错误或无效。

所有插入,更新,移动和放大删除在两个FetchResultsControllers之间都是平滑和动画的。

非常感谢pbasdf。

func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
    switch type {
        case .Insert:
            println("insert")
            if var indexPathNew = newIndexPath {
                if controller == self.elapsedFRC {  indexPathNew = NSIndexPath(forRow: newIndexPath!.row, inSection: 1)  }
                println("N indexPath : \(indexPathNew)")
                self.tableViewEvent.insertRowsAtIndexPaths([indexPathNew], withRowAnimation: .Fade)
            }
        case .Delete:
            println("delete")
            if var indexPathOld = indexPath {
                if controller == self.elapsedFRC {  indexPathOld = NSIndexPath(forRow: indexPath!.row, inSection: 1)  }
                println("O indexPath : \(indexPathOld)")
                self.tableViewEvent.deleteRowsAtIndexPaths([indexPathOld], withRowAnimation: .Fade)
            }
        case .Update:
            println("update")
            if self.showLarge {
                if var indexPathOld = indexPath {
                    if controller == self.elapsedFRC {  indexPathOld = NSIndexPath(forRow: indexPath!.row, inSection: 1)  }
                    println("O indexPath : \(indexPathOld)")
                    if let largeCell = self.tableViewEvent.cellForRowAtIndexPath(indexPathOld) as? LargeTableViewCell {
                        if      indexPathOld.section == 0 {  self.configureLargeCell(largeCell, frc:self.upcomingFRC, row:indexPathOld.row)  }
                        else if indexPathOld.section == 1 {  self.configureLargeCell(largeCell, frc:self.elapsedFRC, row:indexPathOld.row)  }
                    } else {
                        println("******************************************")
                        println("found nil largeCell - configure Large Cell")
                        println("******************************************")
                    }
                } else {
                    println("******************************************")
                    println("found nil indexPath - configure Large Cell")
                    println("******************************************")
                }
            } else {
                if let indexPathOld = indexPath {
                    if let smallCell = self.tableViewEvent.cellForRowAtIndexPath(indexPathOld) as? SmallTableViewCell {
                        if      indexPathOld.section == 0 {  self.configureSmallCell(smallCell, frc:self.upcomingFRC, row:indexPathOld.row)  }
                        else if indexPathOld.section == 1 {  self.configureSmallCell(smallCell, frc:self.elapsedFRC, row:indexPathOld.row)  }
                    } else {
                        println("******************************************")
                        println("found nil smallCell - configure Small Cell")
                        println("******************************************")
                    }
                } else {
                    println("******************************************")
                    println("found nil indexPath - configure Small Cell")
                    println("******************************************")
                }
            }
        case .Move:
            println("move")
            if var indexPathOld = indexPath {
                if controller == self.elapsedFRC {  indexPathOld = NSIndexPath(forRow: indexPath!.row, inSection: 1)  }
                println("O indexPath : \(indexPathOld)")
                self.tableViewEvent.deleteRowsAtIndexPaths([indexPathOld], withRowAnimation: .Fade)
            }
            if var indexPathNew = newIndexPath {
                if controller == self.elapsedFRC {  indexPathNew = NSIndexPath(forRow: newIndexPath!.row, inSection: 1)  }
                println("N indexPath : \(indexPathNew)")
                self.tableViewEvent.insertRowsAtIndexPaths([indexPathNew], withRowAnimation: .Fade)
            }
        default:
            return
    }
}

1 个答案:

答案 0 :(得分:0)

我会修改你的tableView委托和数据源函数,以便他们交换"这些部分结束了。例如:

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if self.fetchedResultsController.sections!.count = 2 {
        section = 1 - section
    }
    let sectionInfo = self.fetchedResultsController.sections![section] as NSFetchedResultsSectionInfo
    return sectionInfo.numberOfObjects
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    var newIndexPath : NSIndexPath
    if self.fetchedResultsController.sections!.count = 2 {
        newIndexPath = NSIndexPath(forRow: indexPath.row, inSection: (1 - indexPath.section))
    } else {
        newIndexPath = indexPath
    }
    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as UITableViewCell
    self.configureCell(cell, atIndexPath: newIndexPath)
    return cell
}

遗憾的是,您必须为每个功能执行此操作。还要注意,如果你使用获取的结果控制器来实现插入/删除等,因为你必须在那里进行相同的调整。