numberOfRowsInSection:核心数据和多个部分的方法 [英] numberOfRowsInSection: method for core data and multiple sections

查看:133
本文介绍了numberOfRowsInSection:核心数据和多个部分的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图显示一个有两个部分的表视图。第一部分将始终具有1行,第二部分将具有与数据点一样多的行。我使用Core Data和以下tableView:numberOfRowsInSection:method ...

   - (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: ]:index 1 beyond bounds [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; //从以前的VC传递的entityOne对象
} 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;
}
}


解决方案

原因是抓取结果控制器(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 您必须在调用表视图方法之前(例如 insertRowsAtIndexPaths )向节号添加1 。






ADDED: configureCell 像这样:

   - (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath 
{
if(indexPath.section == 0){
cell.textLabel.text = entityOne.name; //从上一个VC传递的entityOne对象
} 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: )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索引路径的索引路径,从该部分中减去1。


I am trying to show a table view with 2 sections. The first section will always have 1 row and the second section will have as many rows as data points. I am using Core Data and the following tableView:numberOfRowsInSection: method...

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if (section == 0) {
        return 1;
    } else {
        id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
        return [sectionInfo numberOfObjects];
    }
}

However, I am getting the following error:

Terminating app due to uncaught exception 'NSRangeException', reason: '* -[__NSArrayM objectAtIndex:]: index 1 beyond bounds [0 .. 0]'

Any help will be appreciated. Thanks.

NEW -------------------------------------------------------------------------------

This is the current implementation of the relevant methods:

- (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;
    }
}

解决方案

The reason is that the fetched results controller (FRC) has only one section (section #0), which you want to be displayed in the second section (section #1) of the table view.

This is possible, but you have to map between FRC section numbers and table view section numbers, e.g.

- (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];
    }
}

The same mapping is necessary in cellForRowAtIndexPath.

In the FRC delegate methods didChangeObject, didChangeSection you have to add 1 to the section number before calling the table view methods (e.g. insertRowsAtIndexPaths).


ADDED: configureCell should look like this:

- (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;
    }
}

and didChangeObject like this:

- (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;
    }
}

You probably get the idea:

  • When going from FRC index path to table view index path, add one to the section.
  • When going from table view index path to FRC index path, subtract one from the section.

这篇关于numberOfRowsInSection:核心数据和多个部分的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆