UITableView更新失败

时间:2017-11-23 09:27:27

标签: ios swift uitableview ipad nsfetchedresultscontroller

需要你的帮助! 我只是对iOS 9上的一个错误感到生气。 正如您在下面看到的,它在iOS 11上运行良好

This is working on iOS 11

一开始,我有4个状态为" Nouveau"为了新的。 当我点击" new"单元格,状态变为"恩注意" (对于"等待")。

在iOS 9上,一切都很好,直到最后一个单元格。当我点击最后一个" new"细胞,它不会移动到等待"和#34;新"部分仍在那里。在此之后,表视图不再获得更新,当我更改为另一个viewController并返回到包含表视图的那个时,它将恢复正常。

我正在使用NSFetchedResultsController。数据很好,部分数量很好,按节划分的元素数量很多,标题很好。

在开始的1个部分,标题为" Nouveau"有4个对象 最后,1个部分标题为"恩注意"有4个对象

extension CRDashboardOrdersViewController: UITableViewDataSource {
    func numberOfSections(in tableView: UITableView) -> Int {
        print( self.fetchResult?.sections?.count ?? 0 )
        return self.fetchResult?.sections?.count ?? 0
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        print( self.fetchResult?.sections?.get(index: section)?.numberOfObjects ?? 0 )
        return self.fetchResult?.sections?.get(index: section)?.numberOfObjects ?? 0
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell: CRDashboardOrderTableViewCell = tableView.dequeueReusableCell(withIdentifier: "CRDashboardOrderTableViewCell") as! CRDashboardOrderTableViewCell
        let order: Order = self.fetchResult.object(at: indexPath) as! Order

        cell.order = order

        if let selectedIndexPath = self.selectedIndexPath, selectedIndexPath == indexPath {
            self.tableView.selectRow(at: selectedIndexPath, animated: false, scrollPosition: .none)
        }

        return cell
    }
}

extension CRDashboardOrdersViewController: UITableViewDelegate {
        func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
            self.selectedIndexPath = indexPath
        }

    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        print( self.fetchResult?.sections?.get(index: section)?.name ?? "???" )
        return self.fetchResult?.sections?.get(index: section)?.name ?? "???"
    }
}

extension CRDashboardOrdersViewController: NSFetchedResultsControllerDelegate {
        func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
            self.tableView.beginUpdates()
        }

 func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange sectionInfo: NSFetchedResultsSectionInfo, atSectionIndex sectionIndex: Int, for type: NSFetchedResultsChangeType) {
        print(sectionIndex)
        print(sectionInfo.indexTitle)
        switch type {
        case .insert:
            self.tableView.insertSections(IndexSet(integer: sectionIndex), with: .fade)
        case .delete:
            self.tableView.deleteSections(IndexSet(integer: sectionIndex), with: .fade)
        default:
            break
        }
    }

  func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
        switch type {
        case .update:
            self.tableView.reloadRows(at: [indexPath!], with: .fade)
            if indexPath == self.selectedIndexPath {
                self.selectedIndexPath = indexPath
            }
            break
        case .insert:
            self.tableView.insertRows(at: [newIndexPath!], with: .fade)
            self.selectedIndexPath = nil
            break
        case .delete:
            self.tableView.deleteRows(at: [indexPath!], with: .fade)
            self.selectedIndexPath = nil
            break
        case .move:
            self.tableView.moveRow(at: indexPath!, to: newIndexPath!)
            if indexPath == self.selectedIndexPath {
                self.selectedIndexPath = newIndexPath
            }
            break
        }
    }

 func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
        self.tableView.endUpdates()
    }
}

1 个答案:

答案 0 :(得分:0)

你的cellForRow:和你的FetchedResults代表犯了错误。

当使用FetchedResultsController时,在.update上你不应该使用reloadRows,这会导致问题,而你应该有一个更新单元格模型的方法,如下所示:

func updateCell(atPath indexPath: IndexPath) {
    if let cell = tableView.cellForRow(at: indexPath) as? MyCell {
        updateCell(withCell: cell, atIndexPath: indexPath)
    }
}

func updateCell(withCell cell: MyCell, atIndexPath indexPath: IndexPath) {
    if let MyModel = fetchedResultsController?.object(at: indexPath) {
        cell.model = myModel
}
}

然后在你的委托.update中调用updateCell(AtIndexPath),以更新单元格UI。

您还应该在cellForRow中使用此单元格配置方法