【问题标题】:Ordering core data objects inside a table view section在表格视图部分中对核心数据对象进行排序
【发布时间】:2014-01-28 18:57:01
【问题描述】:

我正在使用 NSSortDescriptors 对核心数据对象进行排序并根据日期属性创建表格视图部分。使用这种 SortDescriptor,表格视图部分按预期排序,但部分内的行也按相同的日期属性排序。有没有办法在每个部分内有另一个订购系统?我猜主要问题是核心数据存储日期对象的日期+时间值,这样就没有对象具有完全相同的日期值。但我需要根据另一个属性对同一部分内的对象进行排序。 谢谢。

这是我的 NSFetchedResultsController 代码:

-(NSFetchedResultsController*)fetchedResultsController{

    if (_fetchedResultsController != nil){
        return _fetchedResultsController;
    }
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc]init];
    NSManagedObjectContext *context = self.managedObjectContext;
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"MyEntity" inManagedObjectContext:context];
    [fetchRequest setEntity:entity];

    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc]initWithKey:@"itemDate" ascending:YES];
    NSSortDescriptor *sortDescriptor1 = [[NSSortDescriptor alloc]initWithKey:@"itemName" ascending:NO];

    NSArray *sortDescriptors = [[NSArray alloc]initWithObjects:sortDescriptor,sortDescriptor1, nil];
    fetchRequest.sortDescriptors = sortDescriptors;
    _fetchedResultsController = [[NSFetchedResultsController alloc]initWithFetchRequest:fetchRequest managedObjectContext:context sectionNameKeyPath:@"sectionIdentifier" cacheName:nil];
    _fetchedResultsController.delegate = self;
    return _fetchedResultsController;
}

编辑问题

这是添加到 cellForRowAtIndexPath 方法中的一段代码:

int indexpathsection = indexPath.section;
    [self sortedSectionForIndex:indexpathsection];
    NSLog(@"INDEXPATH= %ld", (long)indexPath.section);

这是马库斯提出的方法:

- (NSArray*)sortedSectionForIndex:(NSInteger)index
{
    NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"priority" ascending:YES];
    id section = [[self fetchedResultsController] sections][index];
    NSLog(@"INDEX********* = %ld", (long)index);
    NSArray *objects = [section objects];
    NSArray *sorted = [objects sortedArrayUsingDescriptors:@[sort]];
    return sorted;
}

【问题讨论】:

  • 欢迎来到stackoverflow!如果你展示你的数据结构/代码,你会得到更好的答案。
  • 谢谢,我会将我的 NSFetchedResultsController 代码添加到我的问题中。
  • @CorleyBrigman,我已将代码添加到问题中。

标签: ios uitableview core-data


【解决方案1】:

NSFetchedResultsController 用于通过单个排序或一组排序来控制排序顺序。它不是为了做你想做的事。

但你可以做到,只是不够干净。

首先,讨论对一个部分进行排序。这不需要您编写自己的排序算法:

- (NSArray*)sortedSectionForIndex:(NSInteger)index
{
    NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"MyKey" ascending:YES];
    id section = [[self fetchedResultsController] sections][index];
    NSArray *objects = [section objects];
    NSArray *sorted = [objects sortedArrayUsingDescriptors:@[sort]];
    return sorted
}

使用该方法,您可以在想要检索对象时要求对部分进行排序。但是,这是低效的,因为每次您想要触摸 UITableViewController 中的 LOT 的对象时都会进行排序。

取而代之的是,将这个示例与您的 NSFetchedResultsController 及其委托方法集成,以便您存储排序后的数组并保持它们同步。这样,您只需在数据更改时进行排序,而不是在每次方法调用时进行排序。

更新

我提供给您的排序代码不会对NSFetchedResultsController 内部 的内容进行排序。它获取该部分中的内容,对其进行排序并返回排序后的数组。所以你需要使用它返回的内容:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSArray *sorted = [self sortedSectionForIndex:[indexPath section]];
    id object = [sorted objectAtIndex:[indexPath row]];

    id cell = ...; //Now get your cell reference

    //Now update your cell with the data from object

    return cell;
}

【讨论】:

  • 我认为您的回答应该对我有所帮助,但在哪里整合它将是我的下一个问题。你说要将它与我的 NSFetchedResultsController 及其委托方法集成,但是如何,我知道这是一个返回数组的完整方法,但我不知道我应该从哪里调用它......谢谢你的帮助
  • 从任何需要访问数据的地方。 -cellForRowAtIndexPath... 可能是一个不错的起点。
  • Marcus,当从 cellForRowAtIndexPath 方法调用你的方法时,我想我应该这样做:[self sortedSectionForIndex:sectionIndex]; sectionIndex 应该是要排序的部分。
  • 马库斯,我做了如下: int indexPathSection = indexPath.section; [self sortedSectionForIndex:indexPathSection];在 cellForRowAtIndexPath 方法内部。它不会对放在 sortDescriptorWithkey 中的属性进行排序。
  • 马库斯,你能帮我解决我之前的评论吗?我真的很感激。谢谢。
【解决方案2】:

您可以在NSManagedObjectawakeFromFetch 方法中规范化属性的时间组件。

- (void) awakeFromFetch {
    [super awakeFromFetch];
    NSDateComponents* comps = [[NSCalendar currentCalendar] components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit  fromDate:self.itemDate];
    self.itemDate = [[NSCalendar currentCalendar] dateFromComponents:comps];     
}

此外,查看您的代码,您必须告诉NSFetchedResultsController 它应该基于什么分节符。为此,您可以在初始化时为分节符提供一个 keyPath。对于您的情况,不要使用sectionNameKeyPath:@"sectionIdentifier",而是使用第一个排序键:

    _fetchedResultsController = [[NSFetchedResultsController alloc]initWithFetchRequest:fetchRequest managedObjectContext:context sectionNameKeyPath:@"itemDate" cacheName:nil];

【讨论】:

  • 谢谢,但是按照您的建议更改 sectionNameKeyPath 不起作用,这些部分未显示...
  • 我添加了有关如何在托管对象中标准化 itemDate 的时间分量的信息。
猜你喜欢
  • 2010-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-19
  • 1970-01-01
  • 2023-03-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多