将额外的行添加到由NSFetchedResultsController管理的UITableView

时间:2012-03-07 15:36:49

标签: ios ios5 uitableview nsfetchedresultscontroller

我在我的应用中使用UITableViewController表格,我添加了NSFetchedResultsController以提供要在表格中显示的数据(设置self作为其代表)。

但是我想添加一个唯一的单元格作为表格的最后一个单元格,与NSFetchedResultsController的谓词生成的项目无关,我希望这个单元格始终位于表格的底部。

我尝试在表格视图数据源中简单地将这些方法添加1:

- (NSUInteger)numberOfSectionsInTableView:(UITableView *)sender
{
    return [[self.fetchedResultsController sections] count] + 1;
}
- (NSUInteger)tableView:(UITableView *)sender numberOfRowsInSection:(NSUInteger)section
{
    return [[[self.fetchedResultsController sections] objectAtIndex:section] numberOfObjects] + 1;
}

然后捕获这样生成这个额外行的情况(该表只有1个部分):

- (UITableViewCell *)tableView:(UITableView *)sender
         cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.row == [self.fetchedResultsController.fetchedObjects count]) {
        //Generate the last cell in  table.
    } else {
        //Generate the rest of the cells like normal.
    }
    return nil; //To keep the compiler happy.
}

这将检查索引是否是最后一个单元格并正确处理它。

但是我在运行时仍然收到以下错误:

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

知道是什么导致了这个吗?或者是否有更好的方法将额外的行添加到由NSFetchedResultsController控制的表视图中?

4 个答案:

答案 0 :(得分:13)

如果您实现文档中指示的所有数据源方法(更新等),则获取的结果控制器与tableview紧密相关。它会变得相当混乱和黑客。

您的“额外行”可能是该表的页脚视图吗?这总是在底部。让它看起来像一个细胞并不是太多的工作,但从它的外观来看,你希望它看起来与其他细胞看起来不同。

答案 1 :(得分:2)

鉴于该表只有一个部分,这段代码看起来不对:

- (NSUInteger)numberOfSectionsInTableView:(UITableView *)sender
{
    return [[self.fetchedResultsController sections] count] + 1;
}

我怀疑当tableview试图检索第二部分时你的崩溃了; + 1应该被移除。

使用来自获取结果控制器的表格可以做更复杂的事情(参见NSFetchedResultsController prepend a row or section),所以我确信这个简单的案例可以起作用。

答案 2 :(得分:0)

为什么不使用UITableView的内置页眉和页脚视图?

示例:

UIView *customBottomView = [UIView alloc] init... //set up your View (what you called custom bottom cell

self.table.tableFooterView = customBottomView; //或者tableHeaderView

从技术上讲,您正在添加一个视图,该视图显示在添加到表中并由TableView进行奇妙处理的表的下方(或上方)。对于用户,无法确定这是(最后一个)单元格还是仅仅是视图。如果你打算使用像didSelectRowAtIndexPath

这样的方法,你只需要解决

答案 3 :(得分:0)

你绝对不想破解索引路径,并且标题不会,因为单元格有许多你不想丢失的优点。

所以Apple解决这个问题的方法首先要做一个超级实体。然后为要添加的行创建另一个新实体,并使其成为子实体。然后使您正在获取的现有行实体也成为子实体。然后将获取控制器的获取实体更改为此超级实体,这样它将返回结果中的两个子实体。在超级实体中添加sortOrder属性,并在要首先显示的行上将其设置为1,在所有其他行上将其设置为2,这就是使新行显示在顶部的原因。

这就是Apple在iOS Notes应用程序中实现文件夹列表视图的方式。获取控制器的实体是NoteContainer,2个子实体是Account和Folder。顶部的“All iCloud”行是一个帐户,其余的是文件夹。

NoteContainer (sortOrder)
- Account (1)
- Folder (2)

注意垃圾箱也是一个文件夹,但其排序顺序为3,因此最后显示。

这里更广泛的教训是根据您希望它们如何使用获取控制器在UI中显示您的实体,而不是像在规范化的关系数据库中那样。