【问题标题】:Sorting with NSFetchedResultsController使用 NSFetchedResultsController 排序
【发布时间】:2013-08-01 03:13:08
【问题描述】:

使用 XCode 4.6、iOS6、CoreData、UITableViewController、NSFetchesResultsController

我想出了如何将以下日期放入 NSDate 变量中:

todayDate
yesterdayDate
thisWeek
lastWeek
thisMonth
lastMonth
lastYear

现在我想使用 NSFetchedResultsController 根据上述变量中​​的数据将数据放入部分中。我假设我将不得不做一些日期比较:

if ([date1 compare:date2] == NSOrderedDescending) {
NSLog(@"date1 is later than date2");        
} else if ([date1 compare:date2] == NSOrderedAscending) {
    NSLog(@"date1 is earlier than date2");
} else {
    NSLog(@"dates are the same");
}

有些用户可能没有某些部分。 所以,我需要在以下方法中添加什么来确定基于 fetchRequest 的部分数量的帮助:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView

我还需要知道如何将数据划分为单元格numberOfRowsInSection: 并显示到单元格cellforRowAtIndexPath:

一些代码示例会很好!谢谢。

编辑

我还没有集成控制器,但是下面是要获取的代码:

- (void) refreshTable {

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Meeting" inManagedObjectContext:self.managedObjectContext];
    [fetchRequest setEntity:entity];

    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"lastmoddate" ascending:NO];
    NSArray *sortDescriptors = [NSArray arrayWithObjects:sortDescriptor, nil];

    [fetchRequest setSortDescriptors:sortDescriptors];

    [self.managedObjectContext executeFetchRequest:fetchRequest onSuccess:^(NSArray *results) {
        [self.refreshControl endRefreshing];
        self.objects = results;
        [self.tableView reloadData];

    } onFailure:^(NSError *error) {

        [self.refreshControl endRefreshing];
        NSLog(@"An error %@, %@", error, [error userInfo]);
    }];

这是我获取日期的方式:

   NSCalendar *cal = [NSCalendar currentCalendar];
    NSDateComponents *components = [cal components:( NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit ) fromDate:[[NSDate alloc] init]];

    [components setHour:-[components hour]];
    [components setMinute:-[components minute]];
    [components setSecond:-[components second]];
    NSDate *today = [cal dateByAddingComponents:components toDate:[[NSDate alloc] init] options:0]; //This variable should now be pointing at a date object that is the start of today (midnight);

    [components setHour:-24];
    [components setMinute:0];
    [components setSecond:0];
    NSDate *yesterday = [cal dateByAddingComponents:components toDate: today options:0];

    components = [cal components:NSWeekdayCalendarUnit | NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:[[NSDate alloc] init]];

    [components setDay:([components day] - ([components weekday] - 1))];
    NSDate *thisWeek  = [cal dateFromComponents:components];

    [components setDay:([components day] - 7)];
    NSDate *lastWeek  = [cal dateFromComponents:components];

    [components setDay:([components day] - ([components day] -1))];
    NSDate *thisMonth = [cal dateFromComponents:components];

    [components setMonth:([components month] - 1)];
    NSDate *lastMonth = [cal dateFromComponents:components];

【问题讨论】:

  • 你是如何获得你的 fetch 请求的?
  • 您的数据是如何组织的?我了解您使用 Core Data。您的日期变量属性是“用户实体”吗?
  • 我更新了代码。不,变量不是实体的属性。谢谢。
  • 那么每个用户是如何连接到日期的?
  • 另外,您说您需要帮助实现 (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView,因为某些用户可能没有某些部分。这是否意味着您要为每个用户分别调用 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView?

标签: uitableview nsfetchedresultscontroller date-sorting


【解决方案1】:

这就是我会做的。在该模型中创建核心数据模型和“用户”实体。我假设你知道如何做到这一点,但如果你不只是评论和解释。然后只需像使用任何其他实体一样为您的实体创建一个自定义类,并为其赋予 lastmoddate NSDate 属性,另外我将添加一个 creationDate 属性,该属性将等于创建实体的确切日期和时间,以便您可以使用this 作为每个 UserEntity 的标识符。对于要在 UITableView 中创建的每个部分,您还必须拥有一组单独的数组。当您将用户实体添加到模型中时,设置属性,然后因为您说某些用户可能没有每个变量,所以将用户实体不需要的任何变量设置为零。当您初始化您的数组时,只需添加具有适当属性设置为值的用户实体。最后,当您实现 -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 时,您所要做的就是计算数组。

它应该是这样的:

我将调用代表每个用户的实体“UserEntity”(其 NSManagedObject 的类将具有相同的名称)。

以下代码位于您将用于创建和获取实体的类的标头中 - 它可能与您用于显示 UITableView 的类相同。

@interface Class : UITableViewController {
    NSManagedObjectContext *managedObjectContext;
    NSMutableArray *arrayOfArrays;
}

@property (retain, nonatomic) NSManagedObjectContext   *managedObjectContext;
@property (retain, nonatomic) NSMutableArray   *arrayOfArrays;

以下代码包含在您将用于创建和获取实体的任何类的实现中 - 它可能与您用于显示 UITableView 的类相同。

//用于将UserEntity添加到模型(核心数据数据库)并设置其属性

- (UserEntity *)addUserEntityToModel {
     UserEntity *myEnt = (UserEntity *)[NSEntityDescription insertNewObjectForEntityForName:@"UserEntity" inManagedObjectContext:self.managedObjectContext];

   myEnt.creationDate = [NSDate date];
   myEnt. lastmoddate = ...; //replace the '...' with however you get your date
   //add any other values to the appropriate attributes here, any attributes that do not //pertain to the UserEntity simply ignore - they are automatically set to default when they //are created.

    NSError *error = nil;
    if(!managedObjectContext) 
        NSLog(@"managedObejctContext problem at ...");
    else if (![managedObjectContext save:&error]) {
        NSLog(@"context not saved!");;
    } else 
    NSLog(@"context successfully saved.");      
}

//获取UserEntity的

- (NSMutableArray *)getFetchArray {

        NSFetchRequest *request = [[NSFetchRequest alloc] init];
        if(!managedObjectContext) {
            NSLog(@"There is no managedObjectContext at getFetchArray");
        }
           NSEntityDescription *entity = [NSEntityDescription entityForName:@"UserEntity" inManagedObjectContext:managedObjectContext];

        [request setEntity:entity];

        NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"creationDate" ascending:NO];
        NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
        [request setSortDescriptors:sortDescriptors];
        [sortDescriptors release];
        [sortDescriptor release];

        NSError *error = nil;
        NSMutableArray *mutableFetchResults = [[managedObjectContext executeFetchRequest:request error:&error] mutableCopy];
        if (mutableFetchResults == nil) {
            NSLog(@"mutableFetchResults array is nil");
        } 
        [request release];

        return mutableFetchResults;
    }

//设置arrayOfArrays

-(void)createArrayOfArrays {
 NSMutableArray *fetchArray = [self getFetchArray];
  NSMutableArray *todayDateArray = [[NSMutableArray alloc] init];
  NSMutableArray *yesterdayDateArray = [[NSMutableArray alloc] init];
  NSMutableArray *thisWeekArray = [[NSMutableArray alloc] init];
        //... create an array for each section you want

for (UserEntity *ue in fetchArray) {
       if(ue.lastmoddate) { //if the attribute is not nil
        if(ue.lastmoddate isEqual todayDate)
       [todayDateArray insertObject:ue atIndex:0];
     else if (ue.lastmoddate isEqual yesterdayDate)
       [yesterdayDateArray insertObject:ue atIndex:0];
        // ... do this for every section array 
        }
    }

 arrayOfArrays = [[NSMutableArray alloc] initWithObjects:todayDateArray,yesterdayDateArray,...(the rest of the arrays created for each attribute), nil]



  [todayDateArray release];
    [yesterdayDateArray release];
  //  ... release all the arrays except arrayOfArrays and fetchArray     
 }

//设置managedObjectContext

- (id)init {
    self = [super init];

    if (self) {
    AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];//what ever //the name of your appDel is.
        NSManagedObjectContext *context = [appDelegate managedObjectContext];
        self.managedObjectContext = context;

       [self createArrayofArrays];//this first creates the arrayOfArrays and will set it //equal to anything that's saved in the database. If you add an entity you will need to update //it.
    }

    return self;
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    // Return the number of sections.
    return arrayOfArrays.count;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.
    return [[arrayOfArrays objectAtIndex:section] count];
}

//然后在表格视图中显示单元格

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

        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (!cell) {
            cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
        }


        UserEntity *ent = (UserEntity *)[[arrayOfArrays objectAtIndex:indexPath.section] objectAtIndex:indexPath.row];
        cell.accessoryType = UITableViewCellAccessoryBasic;
        if(ent.lastmoddate) { //if lastmoddate is not nil
        cell.textLabel.text = ent. lastmoddate;
        } else {
            NSLog(@"lastmoddate is nil at tableView: cellForRowAtIndexPath");
        }

        NSLog(@"tableView: cellForRowAtIndexPath called.");
        return cell;
    }

【讨论】:

  • 好的,背景就到这里。我有一个使用 CoreData 连接的远程数据库。有一个用户实体和两个其他实体。用户和其他实体之间存在一对多的关系。用于用户名身份验证的用户实体。其他两个之一称为“会议”。当用户登录时,我将获取“会议”实体中的所有对象并将它们显示在 tableViewController 中。在“会议”实体中,除其他属性(大约 20 个)外,其中一个是“lastmoddate”,如该对象的最后修改日期。这就是用于排序的内容。
  • 所以,我想在“会议”实体中获取该用户的所有 NSManagedObjects,并根据“lastmoddate”对它们进行排序,并在以下部分中显示:今天、昨天、上周,上个月等。当用户选择单元格时,另一个 UITableViewController 将拉起显示该对象中属性的所有值。
  • 哦哇..当我输入上述 cmets 时,您写了一个详细的回复。让我回顾一下。谢谢。
  • 哦,好的,我会做一些改变
  • 这里是午夜。我会在上午给你回电话。非常感谢您的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-22
  • 2011-02-01
  • 2013-07-16
  • 2020-01-21
  • 1970-01-01
相关资源
最近更新 更多