我复制了NSFetchedResultsController
的申请documentation中的代码。
如果我想将结果分配给显示结果的UITableView,则表示应该提供sectionNameKeyPath
。
我的目标是根据模型对象名称开头的字符对结果进行分区。即按名称排序。
此代码完全按照名称排序(但按名称排序),但不是对行组进行分区,而是每行都显示在各自的部分中。 (节的数量基本上等于行数。)
我相信我在某个地方犯了一个愚蠢的错误,但我现在花了两个半小时,我看不到任何东西。我只是要粘贴UITableView的委托/数据源方法,我将提供数据。
#pragma mark NSFetchedResultsController
- (NSFetchedResultsController *)fetchedResultsController {
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
NSFetchRequest *fetchRequest = [Place MR_requestAllSortedBy:@"name" ascending:YES];
[fetchRequest setFetchLimit:0];
[fetchRequest setFetchBatchSize:20];
NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[NSManagedObjectContext MR_contextForCurrentThread] sectionNameKeyPath:@"name" cacheName:@"places"];
_fetchedResultsController = theFetchedResultsController;
_fetchedResultsController.delegate = self;
return _fetchedResultsController;
}
#pragma mark UITableViewDelegate
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
ListTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:listTableViewCellIdentifier];
Place *place = [_fetchedResultsController objectAtIndexPath:indexPath];
FAKIcon *categoryIcon = [FFPlaceHandler getIconForPlaceWithCategoryID:place.main_category andSize:CELL_ICON_SIZE];
[categoryIcon addAttribute:NSForegroundColorAttributeName value:FF_WHITE_COLOR];
FAKIcon *circleIcon = [FAKFontAwesome circleIconWithSize:CELL_ICON_CIRCLE_SIZE];
[circleIcon addAttribute:NSForegroundColorAttributeName value:[FFPlaceHandler getColorForPlaceWithCategoryID:place.main_category]];
cell.image.image = [UIImage imageWithStackedIcons:@[circleIcon, categoryIcon] imageSize:CGSizeMake(CELL_ICON_CIRCLE_SIZE, CELL_ICON_CIRCLE_SIZE)];
cell.title.text = place.name;
cell.addressLabel.text = place.place_contact_info.address;
[cell setDistanceWithDistance:[place.distance_from_user floatValue]];
cell.indexPath = indexPath;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
#pragma mark UITableViewDatasource
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
if ([[_fetchedResultsController sections] count] > 1) {
id <NSFetchedResultsSectionInfo> sectionInfo = [[_fetchedResultsController sections] objectAtIndex:section];
return [sectionInfo name];
} else
return nil;
}
- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
return [_fetchedResultsController sectionIndexTitles];
}
- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
return [_fetchedResultsController sectionForSectionIndexTitle:title atIndex:index];
}
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 40.0;
}
- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section {
if ([[_fetchedResultsController sections] count] > 1) {
id <NSFetchedResultsSectionInfo> sectionInfo = [[_fetchedResultsController sections] objectAtIndex:section];
return [sectionInfo numberOfObjects] ;
} else
return 0;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [[_fetchedResultsController sections] count];
}
为什么UITableViewCell
分配了一个部分,而不是按字母顺序划分?
编辑:
通过在核心数据中的place表中添加一个字段来解决它。此字段包含每个记录的第一个字符。在此之后,我改变了我的sectionKeyPath
,如此方法所示:
#pragma mark NSFetchedResultsController
- (NSFetchedResultsController *)fetchedResultsController {
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
NSFetchRequest *fetchRequest = [Place MR_requestAllSortedBy:@"name" ascending:YES];
[fetchRequest setFetchLimit:0];
[fetchRequest setFetchBatchSize:20];
NSFetchedResultsController *theFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[NSManagedObjectContext MR_contextForCurrentThread] sectionNameKeyPath:@"name_first_character" cacheName:@"places"];
_fetchedResultsController = theFetchedResultsController;
_fetchedResultsController.delegate = self;
return _fetchedResultsController;
}
此外,我根据 moby 的建议,将> 1
替换为> 0
!
我现在有一些相当不错的部分:)
答案 0 :(得分:1)
按键路径name
进行切片将为每个具有不同名称值的模型创建一个新部分。因此,如果您有20个模型并且它们都具有不同的name
值,则您将有20个部分。如果您有20个模型,其中10个拥有name
A ,其中10个拥有name
B ,则您将拥有2个部分。< / p>
另外,在你的
中 - (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section {
你正在检查
if ([[_fetchedResultsController sections] count] > 1)
相反,我认为你应该检查count > 0
而不是1。
答案 1 :(得分:1)
一般情况下,如果您使用外部SDK /框架(如魔法记录),我建议您在问题中提及此内容。
另外值得一提的是,要明确......
表视图数据源方法是;
cellForRowAtIndexPath
,numberOfRowsInSection
,numberOfSectionsInTableView
,titleForHeaderInSection
,sectionIndexTitlesForTableView
和sectionForSectionIndexTitle
。表视图委托方法是;
heightForHeaderInSection
。如果你不使用魔法记录,你可以为你的FRC指定一个与你的sectionNameKeyPath
相同的主要(第一)排序描述符......
例如......
NSSortDescriptor *sortDescriptorPrimary = [NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES];
NSSortDescriptor *sortDescriptorSecondary = [NSSortDescriptor sortDescriptorWithKey:<<other attribute>> ascending:YES];
然后设置你的获取请求排序描述符......
[fetchRequest setSortDescriptor:[NSArray arrayWithObjects: sortDescriptorPrimary, sortDescriptorSecondary, nil]];
通过这种方式,您的FRC将以与您的部分相同的顺序将数据提供给表格视图,然后按照您的辅助(或其他)排序描述符进行排序。
也许我已经解决了你的问题...
您正在使用魔法记录排序描述符和sectionNameKeyPath
的{{1}}。
您需要使用每个@"name"
的第一个字母。
所以,如果不考虑太多,你可以选择一个......
@"name"
属性的第一个字母,并将其用作主要排序描述符和节名称关键路径,或者您可以动态评估每个@"name"
属性的第一个字母,并将其用作主要排序描述符和节名称关键路径。
例如......
@"name"
但是我相信(但我不确定)这不会起作用,因为在表视图调用数据源和委托方法之前,FRC可能需要必要的数据。
希望这有助于。