【问题标题】:Indexed NSFetchedResultsController索引的 NSFetchedResultsController
【发布时间】:2012-01-19 14:58:48
【问题描述】:

我如何索引NSFetchedResultsController,以便在tableview 上实现A-Z 索引。

我在初始化程序中看到我可以做 sectionNameKeyPath 但这只是将独特的对象放在它们自己的部分中。

这是我的NSFetchedResultsController 的内容

    - (NSFetchedResultsController *)fetchedResultsController
{
    if (__fetchedResultsController != nil) {
        return __fetchedResultsController;
    }

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];

    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Customer" inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entity];

    [fetchRequest setFetchBatchSize:20];

    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
    NSArray *sortDescriptors = [NSArray arrayWithObjects:sortDescriptor, nil];

    [fetchRequest setSortDescriptors:sortDescriptors];

    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"name" cacheName:@"Customer"];
    aFetchedResultsController.delegate = self;

    self.fetchedResultsController = aFetchedResultsController;

    return __fetchedResultsController;
}  

【问题讨论】:

    标签: ios uitableview core-data nsfetchedresultscontroller


    【解决方案1】:

    像这样实现sectionIndexTitlesForTableView:

    - (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
        return [self.fetchedResultsController sectionIndexTitles];
    }
    

    这将为您提供 tableView 右侧的那些索引。

    如果您希望您的部分具有 A、B、C、D 等名称,您必须实现一个返回对象第一个字母的方法。

    类似这样的:

    - (NSString *)firstLetter {
        [self willAccessValueForKey:@"firstLetter"];
        NSString *firstLetter = [[[self name] substringToIndex:1] uppercaseString];
        [self didAccessValueForKey:@"firstLetter"];
        return firstLetter;
    }
    

    这将进入您的 coredata 实体的自定义子类。

    然后将名为 firstLetter 的瞬态属性添加到您的核心数据实体,并将 NSFetchedResultsController init 中的 sectionNameKeyPath 替换为 firstLetter

    【讨论】:

    • 这非常有效!让我大吃一惊。现在,它只显示我在数据库中的对象索引中的字母。所以如果我只有“测试,测试,测试”,它只显示 T,我如何显示所有字母,我应该如何处理带有“#”的数字?我可以只放置一个类似于其他解决方案的字母数组吗?
    • 在我的 firstLetter 方法中以这种方式计算出数字。 if ([[[NSNumberFormatter alloc] init] numberFromString:firstLetter]){ return @"#"; }
    【解决方案2】:

    @Harris 的回答将在桌子的一侧显示整个字母表。不幸的是,如果您随后点击其中一个 确实 实际上具有相应部分的字母,您会崩溃,例如:

    Terminating app due to uncaught exception 'NSInternalInconsistencyException',
    reason: 'Index title at 3 is not equal to 'K''
    

    【讨论】:

      【解决方案3】:

      如果你想把字母 A-Z 放在一边(即使你没有每个字母都有部分),这会做到:

      - (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
        return [NSArray arrayWithObjects:@"A",@"B",@"C",@"D",@"E",@"F",@"G",@"H",@"I",@"J",@"K",@"L",@"M",@"N",@"O",@"P",@"Q",@"R",@"S",@"T",@"U",@"V",@"W",@"X",@"Y",@"Z",@"#",nil];
      }
      
      - (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index
      {
        index = 0;
        for(id sectionInfo in [_fetchedResultsController sections]){
          if ([[[sectionInfo name] uppercaseString] isEqualToString:title]){
            break;
          }
          index++;
        }
        if (index>=[_fetchedResultsController sections].count){
          return -1;
        }
      
        return [_fetchedResultsController sectionForSectionIndexTitle:title atIndex:index];
      }
      

      【讨论】:

        【解决方案4】:

        正确的版本(ios 7.1 到 8.3):

        - (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
          return [NSArray arrayWithObjects:@"A",@"B",@"C",@"D",@"E",@"F",@"G",@"H",@"I",@"J",@"K",@"L",@"M",@"N",@"O",@"P",@"Q",@"R",@"S",@"T",@"U",@"V",@"W",@"X",@"Y",@"Z",@"#",nil];
        }
        
        - (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index
        {
            NSInteger section = 0;
            for (id <NSFetchedResultsSectionInfo> sectionInfo in [_fetchedResultsController sections])
            {
                if ([sectionInfo.indexTitle compare:title] >= 0)
                {
                    break;
                }
                section++;
            }
            return section;
        }
        

        【讨论】:

          猜你喜欢
          • 2011-08-26
          • 2011-03-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-11-27
          相关资源
          最近更新 更多