简体   繁体   English

在表格视图部分中排序核心数据对象

[英]Ordering core data objects inside a table view section

I am using NSSortDescriptors to order core data objects and create table view sections depending on a date attribute. 我正在使用NSSortDescriptors排序核心数据对象并根据date属性创建表视图部分。 Using this kind of SortDescriptor, the table view sections are ordered as expected, but the rows inside the sections are also ordered by the same date attribute. 使用这种SortDescriptor,表视图部分按预期顺序排序,但部分内部的行也按相同的date属性排序。 Is there a way to have another ordering system inside each section? 是否可以在每个部分中使用另一个订购系统? I guess the main problem is that core data stores date objects with date+time values, that way there are no objects with exactly the same date value. 我猜主要的问题是核心数据存储具有日期+时间值的日期对象,这样就不会有具有完全相同的日期值的对象。 But I would need to order the objects inside the same section based on another attribute. 但是我需要根据另一个属性对同一部分中的对象进行排序。 Thank you. 谢谢。

And here is my code for the NSFetchedResultsController: 这是我的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;
}

EDITED QUESTION 编辑的问题

This is the piece of code added to the cellForRowAtIndexPath method: 这是添加到cellForRowAtIndexPath方法的代码:

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

And this is the method proposed y Marcus: 这是Marcus提出的方法:

- (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;
}

The NSFetchedResultsController is meant for the sort order to be controlled via a single sort or set of sorts. NSFetchedResultsController用于通过单个排序或一组排序控制排序顺序。 It is not intended to do what you are trying to do. 它并非旨在执行您要尝试执行的操作。

But you can do it, it is just not as clean. 但是您可以做到,这还不是那么干净。

First, the discussion of sorting a section. 首先,讨论对节的排序。 This does not require you to write your own sorting algorithm: 这不需要您编写自己的排序算法:

- (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
}

With that method, you can ask for a section to be sorted whenever you want to retrieve an object. 使用该方法,无论何时要检索对象,都可以要求对节进行排序。 However that is inefficient as you are sorting every time you want to touch an object which in a UITableViewController is a LOT . 但是,这很低效,因为每次您要触摸UITableViewController中为LOT的对象时都在进行排序。

Instead, take this example and integrate it with your NSFetchedResultsController and its delegate methods so that you are storing the sorted arrays and keeping them in sync. 相反,请使用此示例,并将其与NSFetchedResultsController及其委托方法集成,以便您存储排序后的数组并使它们保持同步。 That way you are only doing the sort when the data changes instead of on each method call. 这样,您仅在数据更改时进行排序,而不是在每个方法调用时进行排序。

Update 更新

The sort code I provided to you does not sort what is inside of the NSFetchedResultsController . 我提供给您的排序代码不会对NSFetchedResultsController 内部的内容进行排序。 It takes what is in the section, sorts it and returns you the sorted array. 它接受本节中的内容,对其进行排序,然后返回排序后的数组。 So you need to use what it returns: 因此,您需要使用它返回的内容:

- (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;
}

You can normalize the time component of your attribute in the awakeFromFetch method of your NSManagedObject . 您可以在NSManagedObjectawakeFromFetch方法中标准化属性的时间分量。

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

In addition, looking at your code, you have to tell the NSFetchedResultsController on what it should base the section breaks. 另外,查看您的代码,您必须告诉NSFetchedResultsController应该在分节符基础上使用什么。 You do this by providing a keyPath for the section breaks when you initialize it. 为此,您可以在初始化分节符时为其提供keyPath。 For your case, instead of using sectionNameKeyPath:@"sectionIdentifier" , use the first sort key: 对于您的情况,不要使用sectionNameKeyPath:@"sectionIdentifier" ,而是使用第一个排序键:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM