NSFetchedResultsController前置一行或一节 [英] NSFetchedResultsController prepend a row or section

查看:104
本文介绍了NSFetchedResultsController前置一行或一节的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个UITableView,其中填充了标准的NSFetchedResultsController。但是我想在前面添加一行或一个部分(最好是行但是其中任何一个都可以正常工作。)

I have a UITableView populated with a standard NSFetchedResultsController. However I'd like to prepend a row or a section (row preferably but either would works fine really.)

我现在唯一能看到这样做的方法是在处理处理来自NSFetchedResultsController的数据的部分/行时,手动重写所有NSIndexPath,以欺骗它看到索引0处的部分并从索引0处的行开始。但这似乎是一个非常糟糕的想法,很快会让人感到困惑所以我希望最好避免这种情况。

The only way I can possibly see doing this right now is to rewrite all the NSIndexPath's manually when dealing with the section/rows dealing with the data from NSFetchedResultsController to trick it into seeing section at index 0 and starting with row at index 0. This however seems like a really bad idea that would quickly get confusing so I'd like to preferable avoid that.

这是一个很好的例子,当你第一次启动时我会在官方的Twitter应用程序中引导你从朋友列表中添加一些人。

A good example of this would be in the official Twitter app when you start it up for the first time and I walks you through adding some people from your friends list.

红色部分几乎是我想要实现的,我假设的黄色部分是来自NSFetchedResultsControlle r在同一部分(虽然它们的自定义样式可能是一个单独的部分。)

The red section is pretty much what I'd like to achieve, and the yellow section I assume is the results from an NSFetchedResultsController in the same section (though with their custom styling it might be a separate section.)

推荐答案

这可以做到一个相当干净的方式。

This is possible to do in a fairly clean way.

我假设你开始使用标准的tableview设置标准NSFetchResultsController,它使用Apple的示例代码。

I'm assuming you're starting with a standard tableview set up with a standard NSFetchResultsController that uses Apple's sample code.

首先你需要两个实用函数:

First you need two utility functions:

- (NSIndexPath *)mapIndexPathFromFetchResultsController:(NSIndexPath *)indexPath
{
    if (indexPath.section == 0)
        indexPath = [NSIndexPath indexPathForRow:indexPath.row+1 inSection:indexPath.section];

    return indexPath;
}

- (NSIndexPath *)mapIndexPathToFetchResultsController:(NSIndexPath *)indexPath
{
    if (indexPath.section == 0)
        indexPath = [NSIndexPath indexPathForRow:indexPath.row-1 inSection:indexPath.section];

    return indexPath;
}

这些应该是相当自我解释的 - 它们只是处理添加的助手当我们想要从获取的结果控制器使用索引路径来访问表时,或者在执行其他方式时将其删除时,额外的行。

These should be fairly self explanatory - they're just helpers to deal with adding the extra row when we want to use an index path from the fetched results controllers to access the table, or removing it when going the other way.

然后我们需要创建额外的单元格:

Then we need to create the extra cell:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    static NSString *CellIdentifier = @"MyCellId";

    if (indexPath.section == 0 && indexPath.row == 0)
    {
        UITableViewCell *cell;
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil] autorelease];
        cell.selectionStyle = UITableViewCellSelectionStyleGray;
        cell.textLabel.text = NSLocalizedString(@"Extra cell text", nil);

        return cell;
    }

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil] autorelease];
    }

    [self configureCell:cell atIndexPath:indexPath];

    return cell;
}

确保我们正确配置它(只有来自获取结果控制器):

make sure we configure it correctly (configurecell will only be called for cells from the fetch results controller):

// the indexPath parameter here is the one for the table; ie. it's offset from the fetched result controller's indexes
- (void)configureCell:(SyncListViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
    indexPath = [self mapIndexPathToFetchResultsController:indexPath];

    id *obj = [fetchedResultsController objectAtIndexPath:indexPath];
    <... perform normal cell setup ...>
}

告诉tableview它存在:

and tell the tableview it exists:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    NSInteger numberOfRows = 0;

    if ([[fetchedResultsController sections] count] > 0) {
        id <NSFetchedResultsSectionInfo> sectionInfo = [[fetchedResultsController sections] objectAtIndex:section];
        numberOfRows = [sectionInfo numberOfObjects];
    }

    if (section == 0)
        numberOfRows++;

    return numberOfRows;
}

并回复选择:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView deselectRowAtIndexPath:indexPath animated:YES];

    if (indexPath.section == 0 && indexPath.row == 0)
    {
        [self doExtraAction];
        return;
    }

    ... deal with selection for other cells ...

然后重新映射我们从结果控制器获得的任何更新:

and then remap any updates we get from the results controller:

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath {
    UITableView *tableView = self.tableView;

    indexPath = [self mapIndexPathFromFetchResultsController:indexPath];
    newIndexPath = [self mapIndexPathFromFetchResultsController:newIndexPath];

    switch(type) {
        ... handle as normal ...

这篇关于NSFetchedResultsController前置一行或一节的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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