NSFetchedResultsController中带有各个字母节标题的A-Z索引?

11

我有一个NSFetchedResultsController,从Core Data中获取数据,是一个专辑列表。它目前按艺术家排序,所以所有A、B等艺术家在一起。我想添加索引,使用户可以快速跳转到每个字母,并使用下面的代码来实现。问题在于,现在的段标题也是"A"、"B"、"C"等,这意味着我失去了每个艺术家的按字母顺序排列的段标题(例如"Adele"、"America"、"Beatles, The"等)。

我希望索引使用字母A到Z,但段标题按字母顺序显示艺术家名称。点击索引中的字母会跳转到该字母开头的第一个艺术家。如何实现此功能(索引中的字母为字母字符,但段标题为不同的属性)?

编辑:如果我将sectionNameKeyPath设置为author字段,则A-Z索引可见,但字母与名称不同步,例如,如果我点击S,它会带我到以AL开头的艺术家,或者点击G会带我到AB。我不太确定为什么会这样,也许是段索引出了问题?

以下是我正在使用的代码:

在我的NSManagedObject子类中:

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

在我的视图控制器中,创建FRC:

NSFetchedResultsController *byAuthorFRC = [[NSFetchedResultsController alloc] initWithFetchRequest: _fetchRequest
                                                                              managedObjectContext: [[CDManager sharedManager] managedObjectContext]
                                                                                sectionNameKeyPath: @"firstLetter"
                                                                                         cacheName: nil];

下面是我的sectionIndexTitlesForTableView:方法:

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

尝试实现以下方法:- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section - Dan Shelly
@DanShelly 我已经实现了这个 - 在添加索引之前它运行得很好。这一行代码是:return [[[self.fetchedResultsController sections] objectAtIndex: section] name]; - Luke
@DanShelly 我还要指出,如果我将firstLetter作为sectionNameKeyPath使用,那么只会有26个章节标题,每个字母一个。应该有成百上千个。 - Luke
@lukech: 我无法重现这个问题。在我的测试应用中,使用sectionNameKeyPath:@"author"是可以正常工作的。你是否实现了tableView:sectionForSectionIndexTitle:atIndex:方法? - Martin R
@MartinR,不,我以前没有看过/使用过那种方法。你能否提供一个代码示例,告诉我需要在其中做什么? - Luke
显示剩余7条评论
2个回答

20

sectionNameKeyPath:@"author" 是正确的参数,因为这就是您希望将表格分组成部分的方式。标准实现


want your table grouped into sections. The standard implementation

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

返回每个章节标题的第一个字母,因此无需单独编写firstLetter方法。

为了正确地从章节索引到章节的同步,您必须实现表视图数据源方法tableView:sectionForSectionIndexTitle:atIndex:。与获取结果控制器一起使用的标准实现如下:

- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index
{
    return [self.fetchedResultsController sectionForSectionIndexTitle:title atIndex:index];
}

编辑:

Swift:

func sectionIndexTitlesForTableView(tableView: UITableView) -> [String]? {
    return fetchedResultsController.sectionIndexTitles
}

func tableView(tableView: UITableView, sectionForSectionIndexTitle title: String, atIndex index: Int) -> Int {
    return fetchedResultsController.sectionForSectionIndexTitle(title, atIndex: index)
} 

6

Swift 2

将此var添加到您的NSManagedObject中。

class Adherent: NSManagedObject {

    var initialNom: String {
        self.willAccessValueForKey("initialNom")
        let initial = (self.nom as NSString).substringToIndex(1)
        self.didAccessValueForKey("initialNom")
        return initial
    }

}

然后在NSFetchedResultsController构造函数中使用它(不要忘记使用“真实”属性进行排序)。

let nomSort = NSSortDescriptor(key: "nom", ascending: true)
request.sortDescriptors = [nomSort]

self.fetchedResultController = NSFetchedResultsController(
    fetchRequest: request, 
    managedObjectContext: managedObjectContext, 
    sectionNameKeyPath: "initialNom", 
    cacheName: nil)

在你的表格视图中,至少实现以下内容:
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return self.fetchedResultController.sections!.count
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    let sections = self.fetchedResultController.sections!
    let sectionInfo = sections[section]
    return sectionInfo.numberOfObjects
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    [...]
}

func sectionIndexTitlesForTableView(tableView: UITableView) -> [String]? {
    return self.fetchedResultController.sectionIndexTitles
}

func tableView(tableView: UITableView, sectionForSectionIndexTitle title: String, atIndex index: Int) -> Int {
    return self.fetchedResultController.sectionForSectionIndexTitle(title, atIndex: index)
}

func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    return self.fetchedResultController.sectionIndexTitles[section]
}

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