iOS:NSFetchResultsControllersorting瞬态属性(Swift)
举例来说,我有一个名为Tasks的Entity
其中包含一个名为date的Attribute
和一个填充此Tasks Entity
的UITableView
。
这是我目前看到的:
7-Dec-14 09:30 7-Dec-14 11:00 7-Dec-14 13:30 7-Dec-14 16:00
现在我们假设当前时间实际上是7-12月14日12:00,所以前2行已经过去了,而后面的2行却是未来的。 我想将它们分成UITableView
组。
我发现我可以在实体上创build一个Transient Property,如下所示:
var dateGroup: NSNumber { get { if date.compare(NSDate()) == NSComparisonResult.OrderedAscending { return 0 } else { return 1 } } }
这工作,现在显示UITableView
如下,当我设置sectionNameKeyPath:“dateGroup”:
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)上创build一个NSSortDescriptor
,但是这不起作用。
我意识到这是因为我的NSSortDescriptor
“date”属性发生。 但我不知道如何search行date> currentDate,其次是date<currentDate。
我想基本上我想要做的就是在IF中有多于1个的部分。
希望这是有道理的。 你将如何解决这个sorting问题?
更新
好吧,我已经完全重写它使用2 x FetchRequestControllers
self.upcomingFRC(第0节)和self.elapsedFRC(第1节),下面现在工作没有任何错误或nils。
在两个FetchResultsControllers
之间,所有插入,更新,移动和删除操作都很stream畅。
非常感谢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 } }
我会修改你的tableView委托和数据源的function,以便他们“交换”的部分。 例如:
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 }
可悲的是你将不得不为每个function做到这一点。 另外要小心,如果你使用抓取的结果控制器来实现插入/删除等,因为你将不得不作出相同的调整。