如何使用第一个字符作为节名称 [英] How to use the first character as a section name

查看:31
本文介绍了如何使用第一个字符作为节名称的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将 Core Data 用于表格视图,并且我想使用每个结果的第一个字母作为部分标题(因此我可以在侧面获得部分索引).有没有办法用关键路径做到这一点?类似于下面的内容,我使用 name.firstLetter 作为 sectionNameKeyPath (不幸的是这不起作用).

I'm using Core Data for a table view, and I'd like to use the first letter of each of my results as the section header (so I can get the section index on the side). Is there a way to do this with the key path? Something like below, where I use name.firstLetter as the sectionNameKeyPath (unfortunately that doesn't work).

我是否必须手动抓取每个结果的第一个字母并像这样创建我的部分?放入一个新属性来保存第一个字母并将其用作 sectionNameKeyPath 是否更好?

Do I have to grab the first letter of each result manually and create my sections like that? Is it better to put in a new property to just hold the first letter and use that as the sectionNameKeyPath?

NSFetchedResultsController *aFetchedResultsController = 
[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
            managedObjectContext:managedObjectContext
            sectionNameKeyPath:@"name.firstLetter"
            cacheName:@"Root"];

谢谢.

**** 我不确定它是否有区别,但我的结果是日语,按片假名排序.我想用这些片假名作为章节索引.

** ** I'm not sure if it makes a difference, but my results are Japanese, sorted by Katakana. I want to use these Katakana as the section index.

推荐答案

您应该只传递name"作为 sectionNameKeyPath.请参阅此答案对Core Data backed UITableView with索引".

You should just pass "name" as the sectionNameKeyPath. See this answer to the question "Core Data backed UITableView with indexing".

更新
该解决方案仅适用于您只关心快速索引标题滚动条的情况.在这种情况下,您不会显示部分标题.请参阅下面的示例代码.

UPDATE
That solution only works if you only care about having the fast index title scroller. In that case, you would NOT display the section headers. See below for sample code.

否则,我同意 refulgentis 的观点,即瞬态属性是最佳解决方案.此外,在创建 NSFetchedResultsController 时,sectionNameKeyPath 有这个限制:

Otherwise, I agree with refulgentis that a transient property is the best solution. Also, when creating the NSFetchedResultsController, the sectionNameKeyPath has this limitation:

如果这个键路径与由第一种排序指定的fetchRequest 中的描述符,它们必须生成相同的相对顺序.例如,第一个排序描述符在 fetchRequest 中可能指定键对于持久性财产;sectionNameKeyPath 可能指定一个键对于源自于的瞬态属性持久属性.

If this key path is not the same as that specified by the first sort descriptor in fetchRequest, they must generate the same relative orderings. For example, the first sort descriptor in fetchRequest might specify the key for a persistent property; sectionNameKeyPath might specify a key for a transient property derived from the persistent property.

使用 NSFetchedResultsController 的样板 UITableViewDataSource 实现:

Boilerplate UITableViewDataSource implementations using NSFetchedResultsController:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return [[fetchedResultsController sections] count];
}

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

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

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    id <NSFetchedResultsSectionInfo> sectionInfo = [[fetchedResultsController sections] objectAtIndex:section];
    return [sectionInfo numberOfObjects];
}

// Don't implement this since each "name" is its own section:
//- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
//    id <NSFetchedResultsSectionInfo> sectionInfo = [[fetchedResultsController sections] objectAtIndex:section];
//    return [sectionInfo name];
//}

更新 2

对于新的 'uppercaseFirstLetterOfName' 瞬态属性,将新的字符串属性添加到模型中的适用实体并选中瞬态"框.

For the new 'uppercaseFirstLetterOfName' transient property, add a new string attribute to the applicable entity in the model and check the "transient" box.

有几种方法可以实现 getter.如果您正在生成/创建子类,那么您可以将其添加到子类的实现 (.m) 文件中.

There are a few ways to implement the getter. If you are generating/creating subclasses, then you can add it in the subclass's implementation (.m) file.

否则,您可以在 NSManagedObject 上创建一个类别(我将其放在视图控制器实现文件的顶部,但您可以将其拆分为适当的头文件和它自己的实现文件):

Otherwise, you can create a category on NSManagedObject (I put this right at the top of my view controller's implementation file, but you can split it between a proper header and implementation file of its own):

@interface NSManagedObject (FirstLetter)
- (NSString *)uppercaseFirstLetterOfName;
@end

@implementation NSManagedObject (FirstLetter)
- (NSString *)uppercaseFirstLetterOfName {
    [self willAccessValueForKey:@"uppercaseFirstLetterOfName"];
    NSString *aString = [[self valueForKey:@"name"] uppercaseString];

    // support UTF-16:
    NSString *stringToReturn = [aString substringWithRange:[aString rangeOfComposedCharacterSequenceAtIndex:0]];

    // OR no UTF-16 support:
    //NSString *stringToReturn = [aString substringToIndex:1];

    [self didAccessValueForKey:@"uppercaseFirstLetterOfName"];
    return stringToReturn;
}
@end

另外,在这个版本中,不要忘记传递'uppercaseFirstLetterOfName'作为sectionNameKeyPath:

Also, in this version, don't forget to pass 'uppercaseFirstLetterOfName' as the sectionNameKeyPath:

NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext
sectionNameKeyPath:@"uppercaseFirstLetterOfName" // this key defines the sections
cacheName:@"Root"];

并且,在 UITableViewDataSource 实现中取消注释 tableView:titleForHeaderInSection::

And, to uncomment tableView:titleForHeaderInSection: in the UITableViewDataSource implementation:

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
    id <NSFetchedResultsSectionInfo> sectionInfo = [[fetchedResultsController sections] objectAtIndex:section];
    return [sectionInfo name];
}

这篇关于如何使用第一个字符作为节名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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