索引化的NSFetchedResultsController

4
我该如何对 NSFetchedResultsController 进行索引以便在表格视图中实现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;
}  
4个回答

13

像这样实现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实体类的自定义子类中。

然后,在你的CoreData实体类中添加一个瞬态属性,名称为firstLetter,并将NSFetchedResultsController初始化方法中的sectionNameKeyPath替换为firstLetter


这个完美地运作了!让我非常惊讶。但现在它只显示我在数据库中的对象索引中的字母。所以,如果我只有 "测试,测试,测试",它只显示 T。如何显示所有字母以及如何处理带有“#”的数字?我是否可以像其他解决方案一样用字母数组替换掉它? - tofortier
1
在我的firstLetter方法中,我通过以下方式解决了这个数字问题。如果([[[NSNumberFormatter alloc] init] numberFromString:firstLetter]) { return @"#"; } - tofortier

1
@Harris的回答将在表格侧面显示整个字母表。不幸的是,如果您点击其中一个确实有相应部分的字母,您会遇到类似以下内容的崩溃:
Terminating app due to uncaught exception 'NSInternalInconsistencyException',
reason: 'Index title at 3 is not equal to 'K''

0

正确版本(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;
}

0
如果你想在侧边栏上显示字母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];
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接