使用transient属性订购UITableView部分

时间:2014-01-19 20:41:32

标签: ios core-data uitableview

我之前发布过类似的问题,请查看此链接UITableView sections are not ordered as expected 我需要解决的问题如下: 我有一个带定制部分的tableView。节标题取自在名为ToDoItem的NSManagegObject子类中定义的瞬态属性。 transient属性称为sectionIdentifier。在我的tableView viewController中,我有一个带有两个NSSortDescriptors的fetchedResultsController来命令对象:

  NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc]initWithKey:@"todoDueDate" ascending:YES];
    NSSortDescriptor *sortDescriptor1 = [[NSSortDescriptor alloc]initWithKey:@"todoName" ascending:YES];

考虑到瞬态属性不能在NSSortDescriptor中用作initWithKey值,现在根据todoDueDate的属性值而不是sectionIdentifier值(这应该是我的预期顺序)对这些节进行排序。 我把下面的代码形式放在classer下面,sectionIdentifier的第一个定义是ToDoItem类,第二个是tableView vieController类。

-(NSString *)sectionIdentifier{

    [self willAccessValueForKey:@"sectionIdentifier"];
    NSString *tmp = [self primitiveValueForKey:@"sectionIdentifier"];
    [self didAccessValueForKey:@"sectionIdentifier"];


    if ([self.isSomeDay isEqualToString:@"noissomeday"]){//SI NO ES SOMEDAY

    if (!tmp){



        //NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];

        NSCalendar *calendar = [NSCalendar currentCalendar];
        NSInteger comps = (NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit);

        NSDate *today = [NSDate date];
        NSDate *date = self.todoDueDate;


        NSDateComponents *date1Components = [calendar components:comps
                                                        fromDate: today];
        NSDateComponents *date2Components = [calendar components:comps
                                                        fromDate: date];
        today = [calendar dateFromComponents:date1Components];
        date = [calendar dateFromComponents:date2Components];




        NSInteger daysAfterToday = [calendar components:NSDayCalendarUnit
                                               fromDate:today toDate:date options:0].day;
       // NSString *section;
        if (daysAfterToday < 0) {
            tmp  = @"0";
        } else if (daysAfterToday == 0) {
            tmp = @"1";
        } else if (daysAfterToday > 0 && daysAfterToday < 2) {
            tmp = @"2";
        } else {
            tmp = @"3";
        }


        NSLog(@"TODAY = %@", today);
        NSLog(@"DATE = %@", date);
        NSLog(@"DAYS AFTER TODAY = %ld",(long)daysAfterToday);



        [self setPrimitiveValue:tmp forKey:@"sectionIdentifier"];

    }
    }
    //no is someday
    else if ([self.isSomeDay isEqualToString:@"issomeday"]){
        tmp = @"4";
    }
    NSLog(@"Tmp= %@",tmp);
    return tmp;

}

这是我想要获得的部分顺序:

1. OVERDUE, sectionIdentifier = 0
2. TODAY, sectionIdentifier = 1
3. TOMORROW, sectionIdentifier = 2
4. UPCOMING, sectionIdentifier = 3
5. SOMEDAY, sectionIdentifier = 4

ToDoItemsTableViewController.m

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    if (tableView == self.searchDisplayController.searchResultsTableView)
    {
        return 1;
    }
    else
    {
        return [[self.fetchedResultsController sections]count];
    }
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if (tableView == self.searchDisplayController.searchResultsTableView)
    {
        return [self.searchResults count];
    }
    else {
    id<NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections]objectAtIndex:section];
    return [sectionInfo numberOfObjects];

    }
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
   UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    // Configure the cell...

    ToDoItem *toDoItem = nil;



    if (tableView == self.searchDisplayController.searchResultsTableView)
    {
        if (cell==nil) {
            cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
            cell.accessoryType=UITableViewCellAccessoryDisclosureIndicator;

        }
        NSLog(@"Configuring cell to show search results");
        toDoItem = [self.searchResults objectAtIndex:indexPath.row];
        cell.textLabel.text = toDoItem.todoName;



        NSDate *fechaToDO = toDoItem.todoDueDate;

        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
        [dateFormatter setDateFormat:@"EEEE, dd MMMM YYYY"];
        NSString *fechaToDo = [dateFormatter stringFromDate:fechaToDO];

        NSString *valorSomeDay = toDoItem.isSomeDay;
        if ([valorSomeDay isEqualToString:@"issomeday"]){
            cell.detailTextLabel.text = @"Someday";
        }
        else {

        cell.detailTextLabel.text = fechaToDo;
        }
    }
    else
    {


    ToDoItem *todoitem = [self.fetchedResultsController objectAtIndexPath:indexPath];
    cell.textLabel.text = todoitem.todoName;



    NSDate *fechaToDO = todoitem.todoDueDate;

    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
    [dateFormatter setDateFormat:@"EEEE, dd MMMM YYYY"];
    NSString *fechaToDo = [dateFormatter stringFromDate:fechaToDO];



        NSString *valorSomeDay = todoitem.isSomeDay;
        if ([valorSomeDay isEqualToString:@"issomeday"]){
            cell.detailTextLabel.text = @"Someday";
        }
        else {

            cell.detailTextLabel.text = fechaToDo;
        }
    }
    return cell;
}

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    static NSString *header = @"customHeader";

    UITableViewHeaderFooterView *vHeader;

    vHeader = [tableView dequeueReusableHeaderFooterViewWithIdentifier:header];

    if (!vHeader) {
        vHeader = [[UITableViewHeaderFooterView alloc] initWithReuseIdentifier:header];
        vHeader.textLabel.backgroundColor = [UIColor redColor];
        vHeader.textLabel.textColor = [UIColor whiteColor];

        vHeader.contentView.backgroundColor = [UIColor redColor];
    }

    if (section == 0) {
        vHeader.textLabel.backgroundColor = [UIColor redColor];
        vHeader.textLabel.textColor = [UIColor whiteColor];


        vHeader.contentView.backgroundColor = [UIColor redColor];
    }

    else if (section == 1) {
        vHeader.textLabel.backgroundColor = [UIColor orangeColor];
        vHeader.textLabel.textColor = [UIColor blueColor];

        vHeader.contentView.backgroundColor = [UIColor orangeColor];
    }
    else if (section == 2) {
        vHeader.textLabel.backgroundColor = [UIColor greenColor];
        vHeader.textLabel.textColor = [UIColor whiteColor];

        vHeader.contentView.backgroundColor = [UIColor greenColor];
    }
    else if (section == 3) {
        vHeader.textLabel.backgroundColor = [UIColor greenColor];
        vHeader.textLabel.textColor = [UIColor whiteColor];

        vHeader.contentView.backgroundColor = [UIColor greenColor];
    }
    else if (section == 4) {
        vHeader.textLabel.backgroundColor = [UIColor blueColor];
        vHeader.textLabel.textColor = [UIColor whiteColor];

        vHeader.contentView.backgroundColor = [UIColor blueColor];
    }


    vHeader.textLabel.text = [self tableView:tableView titleForHeaderInSection:section];

    return vHeader;
}
-(NSString*)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{

    if (tableView == self.searchDisplayController.searchResultsTableView){
        NSString *valor = [NSString stringWithFormat:@"S E A R C H   R E S U L T S (%d)",[self.searchResults count]];
        return valor;
    }
    else {


    id <NSFetchedResultsSectionInfo> theSection = [[self.fetchedResultsController sections]objectAtIndex:section];
    NSString *sectionname = [theSection name];

    if ([sectionname isEqualToString:@"0"]){

        NSString *valor = [NSString stringWithFormat:@"O V E R D U E   (%d)", [self.tableView
                                                             numberOfRowsInSection:section]];
        return valor;
    }
    else if ([sectionname isEqualToString:@"1"]){

        NSString *valor = [NSString stringWithFormat:@"T O D A Y   (%d)", [self.tableView
                                           numberOfRowsInSection:section]];
        return valor;
    }
    else if ([sectionname isEqualToString:@"2"]){

        NSString *valor = [NSString stringWithFormat:@"T O M O R R O W   (%d)", [self.tableView
                                                             numberOfRowsInSection:section]];
        return valor;
    }
    else if ([sectionname isEqualToString:@"3"]){

        NSString *valor = [NSString stringWithFormat:@"U P C O M I N G   (%d)", [self.tableView
                                                                                 numberOfRowsInSection:section]];
        return valor;
    }

    else if ([sectionname isEqualToString:@"4"]){

        NSString *valor = [NSString stringWithFormat:@"S O M E D A Y    (%d)", [self.tableView
                                                                                 numberOfRowsInSection:section]];
        return valor;
    }


    if ([[self.fetchedResultsController sections]count]>0){
        id<NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections]objectAtIndex:section];
        return [sectionInfo name];
    }
    else{
        return nil;
    }
    }

}


#pragma mark - Fetched Results Controller Section

-(NSFetchedResultsController*)fetchedResultsController{

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

    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc]initWithKey:@"todoDueDate" ascending:YES];
    NSSortDescriptor *sortDescriptor1 = [[NSSortDescriptor alloc]initWithKey:@"todoName" ascending:YES];

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

1 个答案:

答案 0 :(得分:1)

我假设“SOMEDAY”条目是todoDueDate未指定的条目。 问题是第一个排序描述符“todoDueDate”必须兼容 部分标识符。因此,您不能使用两个单独的属性todoDueDateisSomeDay部分。

因此,您应该分配这些对象,而不是使用单独的属性isSomeDay 一个远未来的价值:

self.todoDueDate = [NSDate distantFuture];

以便在所有其他对象之后自动排序。 然后你可以在sectionIdentifier方法中执行类似的操作:

if ([self.todoDueDate isEqualToDate:[NSDate distantFuture]) {
    tmp = @"4";
} else {
    // ... your other checks for overdue, today, tomorrow, upcoming
}

同样在viewForHeaderInSection中,您不应该检查部分编号, 但对于部分名称(“0”,“1”,......)。原因是某个部分可能是空的: 如果没有“OVERDUE”对象,那么“TODAY”就是#0部分。

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    id <NSFetchedResultsSectionInfo> theSection = [[self.fetchedResultsController sections] objectAtIndex:section];

    NSString *tmp = [theSection name];
    if ([tmp isEqualToString:@"0"]) {
        // OVERDUE
    } else if ([tmp isEqualToString:@"1"]) {
        // TODAY
    } else 
    // and so on ...
}