numberOfRowsInSection:核心数据和多个部分的方法
Posted
技术标签:
【中文标题】numberOfRowsInSection:核心数据和多个部分的方法【英文标题】:numberOfRowsInSection: method for core data and multiple sections 【发布时间】:2013-01-13 03:33:25 【问题描述】:我正在尝试显示一个包含 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) 只有一个部分 (section #0),您希望将其显示在第二部分 (section #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 索引路径时,从该部分中减去一个。【讨论】:
谢谢。正如您所解释的,我已经能够在 numberOfRowsInSection: 和 didChangeSection: 方法中进行映射。但是,我很难在 cellForRowAtIndexPath: 和 didChangeObject: 方法中进行映射。你能帮我处理这两个映射吗? @AveLeon:如果您将这些功能的当前实现添加到您的问题中,我可以尝试提供帮助。 谢谢。我已经做了。如您所见,我无法使用索引路径更改方法中的节号。 非常感谢!这当然有帮助! 问题:您是否故意在 NSFetchedResultsChangeUpdate 案例中保留 indexPath 不变?以上是关于numberOfRowsInSection:核心数据和多个部分的方法的主要内容,如果未能解决你的问题,请参考以下文章
ReloadData 不会触发 tableView:numberOfRowsInSection:
对成员 '(_:numberOfRowsInSection:)' 的模糊引用
数组未与 tableView(numberOfRowsInSection) 方法连接