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

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

问题描述

我使用Core Data作为表视图,我想使用我的每个结果的第一个字母作为节头(因此我可以得到节索引在一边)。有没有办法做到这一点与关键路径?像下面这样,我使用 name.firstLetter 作为 sectionNameKeyPath (不幸的是不工作)。

我必须手动抓取每个结果的第一个字母并创建我的部分吗?是否最好放入一个新的属性只保留第一个字母,并使用 sectionNameKeyPath

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

谢谢。



**我不知道它是否有所作为,但我的结果是日本,按片假名排序。我想使用这些片假名作为节索引。

解决方案

你应该传递name作为sectionNameKeyPath。请参阅此 answer 问题核心数据支持的UITableView与索引。



UPDATE

该解决方案仅在您只关心快速索引标题滚动器时才有效。在这种情况下,您不会显示节标题。请参阅下面的示例代码。



否则,我同意refulgentis一个瞬态属性是最好的解决方案。此外,在创建NSFetchedResultsController时, sectionNameKeyPath 有此限制:


如果此键路径不是与fetchRequest中第一个排序
描述符指定的
相同,它们必须
生成相同的相对排序。
例如,fetchRequest中的第一个排序描述符
可能为持久性属性指定键
;
sectionNameKeyPath可以为从
派生的临时属性指定一个键
持久属性。


Boilerplate UITableViewDataSource实现使用NSFetchedResultsController:

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

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

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

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

//不要实现它,因为每个name是它自己的部分:
// - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection: (NSInteger)section {
// id< NSFetchedResultsSectionInfo> sectionInfo = [[fetchedResultsController sections] objectAtIndex:section];
// return [sectionInfo name];
//}

UPDATE 2 b
$ b

对于新的uppercaseFirstLetterOfName瞬态属性,向模型中适用的实体添加一个新的字符串属性,并检查transient框。



有几种方法来实现getter。



否则,你可以在NSManagedObject(I put)上创建一个类别。如果你正在生成/创建子类,你可以将它添加到子类的实现这个在我的视图控制器的实现文件的顶部,但你可以在一个适当的标题和自己的实现文件之间):

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

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

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

//或者没有UTF-16支持:
// NSString * stringToReturn = [aString substringToIndex:1];

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

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

  NSFetchedResultsController * aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext 
sectionNameKeyPath:@uppercaseFirstLetterOfName//此键定义节
cacheName:@Root];

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

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


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).

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"];

Thanks.

**EDIT: ** 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.

解决方案

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.

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

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.

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];
//}

UPDATE 2

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

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.

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

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"];

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天全站免登陆