Я создаю табличный вид, который имеет расширяемую таблицу с разделами (пучками), являющимися пользовательским UITableViewCell, а также строками (приятелями) - вы можете создавать произвольные пучки друзей. Я также заполняю таблицу, используя NSFetchedResultsController, который я успешно выполнил. Трудность я имею при добавлении кучи к основным данным, NSFetchedResultsController бросает это исключение:Как использовать NSFetchedResultsController для добавления раздела (с пользовательскими ячейками ячеек) в контроллере табличного представления?
CoreData: error: Serious application error. An exception was caught from the delegate of NSFetchedResultsController during a call to -controllerDidChangeContent:. attempt to insert row 0 into section 1, but there are only 0 rows in section 1 after the update with userInfo (null)
Я хотел бы иметь возможность добавить кучу (в модальном диалоге) и он автоматически отображаться в представлении таблицы (в соответствии с возможностями NSFetchedResultController), но он генерирует исключение (не разбивается), как показано выше, и раздел не добавляется.
Вот код NSFetchedResultsController:
Инициализация (инициализируется при загрузке в виде таблицы)
lazy var fetchedResultsController: NSFetchedResultsController = {
let bunchesFetchRequest = NSFetchRequest(entityName: Constants.CoreData.bunch)
// Sort bunches by bunch name, in alphabetical order, not caring about capitalization
let primarySortDescriptor = NSSortDescriptor(key: Constants.CoreData.Bunch.name, ascending: true, selector: "caseInsensitiveCompare:")
bunchesFetchRequest.sortDescriptors = [primarySortDescriptor]
// TODO: Answer question: Do we need this, does this benefit us at all, and how does prefetching work?
bunchesFetchRequest.relationshipKeyPathsForPrefetching = [Constants.CoreData.Bunch.buddies]
let frc = NSFetchedResultsController(
fetchRequest: bunchesFetchRequest,
managedObjectContext: CoreDataStackManager.sharedInstance().managedObjectContext!,
sectionNameKeyPath: Constants.CoreData.Bunch.name,
cacheName: nil
)
frc.delegate = self
return frc
}()
Таблица Посмотреть Методы
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// sections are the bunches
if let sections = fetchedResultsController.sections {
return sections.count
}
return 0
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// sections are the bunches (this is for when sectionNameKeyPath is set)
if let sections = fetchedResultsController.sections {
let currentSection = sections[section] as! NSFetchedResultsSectionInfo
let bunch = currentSection.objects[0] as! Bunch
// Return the number of buddies in this section (bunch)
return bunch.buddies.count
}
return 0
}
func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
if let sections = fetchedResultsController.sections {
let currentSection = sections[section] as! NSFetchedResultsSectionInfo
let bunch = currentSection.objects[0] as! Bunch
// Create BunchTableViewCell
let headerCell: BunchTableViewCell = tableView.dequeueReusableCellWithIdentifier(bunchCellIdentifier) as! BunchTableViewCell
headerCell.bunchNameLabel.text = bunch.name
return headerCell
}
return nil
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell: BuddyInBunchTableViewCell = tableView.dequeueReusableCellWithIdentifier(buddyInBunchCellIdentifier, forIndexPath: indexPath) as! BuddyInBunchTableViewCell
if let sections = fetchedResultsController.sections {
let currentSection = sections[indexPath.section] as! NSFetchedResultsSectionInfo
let bunch = currentSection.objects[0] as! Bunch
let buddy: Buddy = bunch.getBuddiesInBunch()[indexPath.row]
cell.buddyFullNameLabel.text = buddy.getFullName()
}
return cell
}
func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 50.0
}
NSFetchedResultsController Методы
func controllerWillChangeContent(controller: NSFetchedResultsController) {
self.tableView.beginUpdates()
}
func controller(
controller: NSFetchedResultsController,
didChangeObject anObject: AnyObject,
atIndexPath indexPath: NSIndexPath?,
forChangeType type: NSFetchedResultsChangeType,
newIndexPath: NSIndexPath?) {
switch type {
case NSFetchedResultsChangeType.Insert:
// Note that for Insert, we insert a row at the __newIndexPath__
if let insertIndexPath = newIndexPath {
// AAAAAAAAAA
self.tableView.insertRowsAtIndexPaths([insertIndexPath], withRowAnimation: UITableViewRowAnimation.Fade)
// BBBBBBBBBB
// self.tableView.insertSections(NSIndexSet(index: insertIndexPath.section), withRowAnimation: UITableViewRowAnimation.Fade)
}
case NSFetchedResultsChangeType.Delete:
// Note that for Delete, we delete the row at __indexPath__
if let deleteIndexPath = indexPath {
self.tableView.deleteRowsAtIndexPaths([deleteIndexPath], withRowAnimation: UITableViewRowAnimation.Fade)
}
case NSFetchedResultsChangeType.Update:
// Note that for Update, we update the row at __indexPath__
// Not yet implemented
break
case NSFetchedResultsChangeType.Move:
// Note that for Move, we delete the row at __indexPath__
if let deleteIndexPath = indexPath {
self.tableView.deleteRowsAtIndexPaths([deleteIndexPath], withRowAnimation: UITableViewRowAnimation.Fade)
}
// Note that for Move, we insert a row at the __newIndexPath__
if let insertIndexPath = newIndexPath {
self.tableView.insertRowsAtIndexPaths([insertIndexPath], withRowAnimation: UITableViewRowAnimation.Fade)
}
}
}
func controller(
controller: NSFetchedResultsController,
didChangeSection sectionInfo: NSFetchedResultsSectionInfo,
atIndex sectionIndex: Int,
forChangeType type: NSFetchedResultsChangeType) {
switch type {
case .Insert:
// AAAAAAAAAA
let sectionIndexSet = NSIndexSet(index: sectionIndex)
self.tableView.insertSections(sectionIndexSet, withRowAnimation: UITableViewRowAnimation.Fade)
// BBBBBBBBBBB
// break
case .Delete:
let sectionIndexSet = NSIndexSet(index: sectionIndex)
self.tableView.deleteSections(sectionIndexSet, withRowAnimation: UITableViewRowAnimation.Fade)
default:
break
}
}
func controllerDidChangeContent(controller: NSFetchedResultsController) {
self.tableView.endUpdates()
}
Примечание: если я закомментируйте строки под AAAAAAAAAA и раскомментируйте в BBBBBBBBBB, я могу видеть клетки появляются очень кратко, но каждая ячейка ниже этой вставленной клетки исчезает, и я получаю эту ошибку, а не много раз:
no index path for table cell being reused
Любая помощь/предложение оценены!