繁体   English   中英

在UITableView的一部分上使用NSFetchedResultsController

[英]Using NSFetchedResultsController on a part of UITableView

我在UISplitViewController有一个UITableViewController 这个tableViewController接收两件事:

  1. 发票阵列
  2. 客户对象

因此,我正在做的是在UITableView的第一部分(或Section 0 )中填充发票详细信息。

对于第二部分,我将使用NSFetchedResultsController来获取具有invoice == nil的客户的所有属性,并将其显示在表格视图的第二部分中。

因此,基本上,仅在UITableViewController的一部分而不是整个对象上使用NSFetchedResultsController

现在,一切正常。 但是,当我点击第2部分的行时,我为用户提供了将该property添加到新发票的功能。 当我这样做时,会出现以下错误:

CoreData: error: Serious application error.  An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:.  Invalid update: invalid number of rows in section 0.  The number of rows contained in an existing section after the update (2) must be equal to the number of rows contained in that section before the update (1), plus or minus the number of rows inserted or deleted from that section (0 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out). with userInfo (null)

不知道为什么会这样。 我了解fetchedResultsController期望使用第0节,但我确保手动将其强制仅使用第1节。

供参考的代码是:

func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
    switch (type) {
    case .Insert:
        if let indexPath = newIndexPath {
            let editedNewIndexPath = NSIndexPath(forRow: indexPath.row, inSection: 1)
            tableView.insertRowsAtIndexPaths([editedNewIndexPath], withRowAnimation: .Fade)
        }
        break;
    case .Delete:
        if let indexPath = indexPath {
            let editedCurrentIndexPath = NSIndexPath(forRow: indexPath.row, inSection: 1)
            tableView.deleteRowsAtIndexPaths([editedCurrentIndexPath], withRowAnimation: .Fade)
        }
        break;
    case .Update:
        if let indexPath = indexPath {
            let editedCurrentIndexPath = NSIndexPath(forRow: indexPath.row, inSection: 1)
            if let cell = tableView.cellForRowAtIndexPath(editedCurrentIndexPath){
                configureCell(cell, atIndexPath: editedCurrentIndexPath)
                //tableView.selectRowAtIndexPath(indexPath, animated: true, scrollPosition: .None)
            }
        }
        break;
    case .Move:
        if let indexPath = indexPath {
            let editedCurrentIndexPath = NSIndexPath(forRow: indexPath.row, inSection: 1)
            tableView.deleteRowsAtIndexPaths([editedCurrentIndexPath], withRowAnimation: .Fade)
        }

        if let newIndexPath = newIndexPath {
            let editedNewIndexPath = NSIndexPath(forRow: newIndexPath.row, inSection: 1)
            tableView.insertRowsAtIndexPaths([editedNewIndexPath], withRowAnimation: .Fade)
        }
        break;
    }
}

// MARK: - Table view data source

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 2
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if section == 0{
        if let ivData = self.invoices{
            print("Section0 - \(ivData.count)")
            return ivData.count
        }
    }
    else if section == 1{
        if let sections = fetchedResultsController.sections {
            let sectionInfo = sections[0]
            print("Section1 - \(sectionInfo.numberOfObjects)")
            if sectionInfo.numberOfObjects > 0{
                return sectionInfo.numberOfObjects
            }
            else{
                return 1
            }
        }
    }
    return 0
}

保存新发票的代码是:

do{
                    self.invoices!.append(billRecord as! InvoiceInfo)
                    try billRecord.managedObjectContext?.save()
                    try self.customer!.managedObjectContext?.save()
                    try record.managedObjectContext?.save()
                    //self.lookUpLotsWithoutBills()
                    self.tableView.reloadData()

                }
                catch{
                    self.invoices!.removeObject(ivRecord)
                    let alertController = UIAlertController(title: "Unexpected Error", message: "Your data could not be updated. Please try again later.", preferredStyle: .Alert)
                    alertController.addAction(UIAlertAction(title: "Done", style: .Cancel, handler: nil))
                    self.presentViewController(alertController, animated: true, completion: nil)
                }

这有什么问题吗?

看起来您的FRC正常工作,但是您的代码没有告诉表视图有关添加到第0部分的新发票行。目前尚不清楚原因,但我想猜测是因为FRC在添加发票之后但在调用表格上的重新加载数据之前,将触发更新。 那时,第0节的行计数是错误的,您还没有告诉表。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM