numberOfRowsInSection: метод для основных данных и нескольких разделов
Я пытаюсь показать табличное представление с 2 разделами. В первом разделе всегда будет 1 строка, а во втором - столько строк, сколько точек данных. Я использую Core Data и следующий tableView:numberOfRowsInSection: метод...
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (section == 0) {
return 1;
} else {
id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
return [sectionInfo numberOfObjects];
}
}
Однако я получаю следующую ошибку:
Завершение работы приложения из-за необработанного исключения "NSRangeException", причина: '* - [__ NSArrayM objectAtIndex:]: индекс 1 за пределами [0 .. 0]'
Любая помощь будет оценена. Благодарю.
НОВОЕ ------------------------------------------------- ------------------------------
Это текущая реализация соответствующих методов:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (section == 0) {
return 1;
} else {
NSUInteger frcSection = section - 1;
id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:frcSection];
return [sectionInfo numberOfObjects];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
[self configureCell:cell atIndexPath:indexPath];
return cell;
}
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 0) {
cell.textLabel.text = entityOne.name; //entityOne object passed from previous VC
} else {
entityTwo = [self.fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = entityTwo.name;
}
}
- (void)controller:(NSFetchedResultsController *)controller
didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
atIndex:(NSUInteger)sectionIndex
forChangeType:(NSFetchedResultsChangeType)type
{
NSUInteger frcSectionIndex = 0;
frcSectionIndex = sectionIndex + 1;
switch(type) {
case NSFetchedResultsChangeInsert:
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:frcSectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:frcSectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controller:(NSFetchedResultsController *)controller
didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath
forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath
{
UITableView *tableView = self.tableView;
switch(type) {
case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
[self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
break;
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
1 ответ
Причина в том, что контроллер полученных результатов (FRC) имеет только один раздел (раздел # 0), который вы хотите отобразить во втором разделе (раздел # 1) табличного представления.
Это возможно, но вы должны сопоставить номера разделов FRC и номера разделов табличного представления, например
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (section == 0) {
return 1;
} else {
NSUInteger frcSection = section - 1;
id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:frcSection];
return [sectionInfo numberOfObjects];
}
}
Такое же отображение необходимо в cellForRowAtIndexPath
,
В FRC делегатские методы didChangeObject
, didChangeSection
Вы должны добавить 1 к номеру раздела перед вызовом методов табличного представления (например, insertRowsAtIndexPaths
).
ДОБАВЛЕНО: configureCell
должен выглядеть так:
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 0) {
cell.textLabel.text = entityOne.name; //entityOne object passed from previous VC
} else {
NSIndexPath *frcIndexPath = [NSIndexPath indexPathForRow:indexPath.row inSection:(indexPath.section - 1)];
entityTwo = [self.fetchedResultsController objectAtIndexPath:frcIndexPath];
cell.textLabel.text = entityTwo.name;
}
}
а также didChangeObject
как это:
- (void)controller:(NSFetchedResultsController *)controller
didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath
forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath
{
UITableView *tableView = self.tableView;
NSIndexPath *tvIndexPath = [NSIndexPath indexPathForRow:indexPath.row inSection:(indexPath.section + 1)];
NSIndexPath *tvNewIndexPath = [NSIndexPath indexPathForRow:newIndexPath.row inSection:(newIndexPath.section + 1)];
switch(type) {
case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:@[tvNewIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:@[tvIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
[self configureCell:[tableView cellForRowAtIndexPath:tvIndexPath] atIndexPath:tvIndexPath];
break;
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:@[tvIndexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView insertRowsAtIndexPaths:@[tvNewIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
Вы, вероятно, поняли идею:
- При переходе от пути индекса FRC к пути индекса табличного представления добавьте его в раздел.
- При переходе от пути индекса табличного представления к пути индекса FRC вычтите его из раздела.