2010-12-11 36 views
22

我开发了一个使用Core Data的应用程序。在一个UITableView中,我想显示我的实体列表,按照对象的保存日期排序。当我这样做:一个NSFetchedResultsController,其日期为sectionNameKeyPath

fetchedResultsController = [[NSFetchedResultsController alloc] 
          initWithFetchRequest:fetchRequest 
          managedObjectContext:managedObjectContext 
           sectionNameKeyPath:@"date" 
             cacheName:nil]; 

我得到的每个对象一个新的部分,因为这个代码组根据秒的日期了。但我想要一个按日期分组的对象列表,但只能根据日期,月份和年份进行分组。这是可能的和如何?

非常感谢您的帮助! ;)

回答

41

这应该为你做的伎俩:

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { 
    NSString *rawDateStr = [[[self.fetchedResultsController sections] objectAtIndex:section] name]; 
    // Convert rawDateStr string to NSDate... 
    NSDateFormatter *formatter = [[[NSDateFormatter alloc] init] autorelease]; 
    [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss ZZ"]; 
    NSDate *date = [formatter dateFromString:rawDateStr]; 

    // Convert NSDate to format we want... 
    [formatter setDateFormat:@"d MMMM yyyy"]; 
    NSString *formattedDateStr = [formatter stringFromDate:date]; 
    return formattedDateStr; 
} 

[编辑]

物权看到你的评论和你想达到什么样的,你可以创建一个短暂NSDate属性(非永久性),其格式与上述代码类似(即没有H:mm:ss ZZZZ),并将该属性用作sectionNameKeyPath值。

在一个 foo对象一言以蔽之

所以,用fooDatefooDateTransient属性,你会:

  1. 让您foo.fooDate属性

  2. 使用以上(或类似)的代码转换并分配NSDate结果为foo.fooDateTransient

  3. 使用fooDateTransient作为您的sectionNameKeyPath创建fetchedResultsController对象时。

PS:我没有测试过,但应该值得一试!

祝你好运, 罗格

+0

谢谢,但那是如何显示节的标题的方式。但它不会将同一日期的两个对象分组。每个对象还有一个部分。 – 2010-12-12 09:45:21

+0

够公平的,我已经编辑了我的答案,提出了一种可以尝试的替代方法。 – Rog 2010-12-12 20:56:43

+0

非常感谢你Rog!这工作。谢谢! ;) – 2010-12-13 06:38:39

0

我认为这会更好。

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { 

    // Replace DataClassObject with whatever object your using 
    DataClassObject *tempObject = [[sectionInfo objects] objectAtIndex:0]; 

    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 
    [formatter setDateFormat:@"d MMMM yyyy"]; 
    NSString *formattedDateStr = [formatter stringFromDate:tempObject.date]; 
    [dateFormatter release] 

    return formattedDateStr; 
} 
+0

我一开始同意你的意见,但是在尝试了这个之后,我意识到这个过程贯穿了我所有的批处理过程,并且在一个大型数据集上真的很慢。使用@ Rog的解决方案要快一点。 – 2012-01-15 22:41:41

-1

我使用@ BoltClock的独角兽和@ Rog的anwser时有同样的问题。 简单地增加了一个短暂的NSString * sectionTitle我的管理对象,使用@“sectionTitle”作为sectionNameKeyPath和创建自定义的getter像这样:

-(NSString *)sectionTitle 
{ 
    NSDate *_now = [NSDate date]; 
    NSDate *_today = [_now dateByAddingTimeInterval: -86400.0]; 
    NSDate *_yesterday = [_now dateByAddingTimeInterval: -172800.0]; 
    NSDate *_thisWeek = [_now dateByAddingTimeInterval: -604800.0]; 
    NSDate *_lastWeek = [_now dateByAddingTimeInterval: -1209600.0]; 
    NSDate *_thisMonth = [_now dateByAddingTimeInterval: -2629743.0]; 
    // if better precision required use something more sophisticated for month... 

    double today = [_today timeIntervalSince1970]; 
    double yesterday = [_yesterday timeIntervalSince1970]; 
    double thisWeek = [_thisWeek timeIntervalSince1970]; 
    double lastWeek = [_lastWeek timeIntervalSince1970]; 
    double thisMonth = [_thisMonth timeIntervalSince1970]; 

    [self willAccessValueForKey:@"timestamp"]; 
     double ts = [self.timestamp timeIntervalSince1970]; 
    [self didAccessValueForKey:@"timestamp"]; 

    NSString *title = @""; 
    if(ts >= today) title = NSLocalizedString(@"TODAY",nil); 
    else if (ts >= yesterday) title = NSLocalizedString(@"YESTERDAY",nil); 
    else if (ts >= thisWeek) title = NSLocalizedString(@"THIS WEEK",nil); 
    else if (ts >= lastWeek) title = NSLocalizedString(@"LAST WEEK",nil); 
    else if (ts >= thisMonth) title = NSLocalizedString(@"THIS MONTH",nil); 

    return title; 
} 
+1

切勿使用'dateByAddingTimeInterval'来计算日期。你有没有考虑过闰年会发生什么? – 2013-12-03 11:13:26

+0

是啊,这只是一个基本的例子给你的想法 – 2013-12-03 11:24:52

+1

给代码与糟糕的代码总是一个坏主意。你的整个事情可以用一个简单的NSDateFormatter来完成,该NSDateFormatter的doRelativeDateFormatting选项设置为YES。 – Gargoyle 2014-05-27 18:37:39

1

以下是雨燕3溶液按日期排序,但有部分标题对应于个别日子。

  1. 将一个名为daySectionIdentifier的瞬态属性添加到Core Data中的实体。
  2. 重新生成您的NSManagedObject子类。删除可能在Entity+CoreDataProperties.swift中生成的daySectionIdentifier的属性。
  3. Entity+CoreDataClass.swift文件,添加下面的getter方法daySectionIdentifier

    // Transient property for grouping a table into sections based 
    // on day of entity's date. Allows an NSFetchedResultsController 
    // to sort by date, but also display the day as the section title. 
    // - Constructs a string of format "YYYYMMDD", where YYYY is the year, 
    //  MM is the month, and DD is the day (all integers). 
    
    public var daySectionIdentifier: String? { 
        let currentCalendar = Calendar.current 
        self.willAccessValue(forKey: "daySectionIdentifier") 
        var sectionIdentifier = "" 
        if let date = self.date as? Date { 
         let day = currentCalendar.component(.day, from: date) 
         let month = currentCalendar.component(.month, from: date) 
         let year = currentCalendar.component(.year, from: date) 
    
         // Construct integer from year, month, day. Convert to string. 
         sectionIdentifier = "\(year * 10000 + month * 100 + day)" 
        } 
        self.didAccessValue(forKey: "daySectionIdentifier") 
    
        return sectionIdentfier 
    } 
    
  4. 在你UITableViewController实现,添加以下方法:

    override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { 
        var sectionTitle: String? 
        if let sectionIdentifier = fetchedResultsController.sections?[section].name { 
         if let numericSection = Int(sectionIdentifier) { 
          // Parse the numericSection into its year/month/day components. 
          let year = numericSection/10000 
          let month = (numericSection/100) % 100 
          let day = numericSection % 100 
    
          // Reconstruct the date from these components. 
          var components = DateComponents() 
          components.calendar = Calendar.current 
          components.day = day 
          components.month = month 
          components.year = year 
    
          // Set the section title with this date 
          if let date = components.date { 
           sectionTitle = DateFormatter.localizedString(from: date, dateStyle: .medium, timeStyle: .none) 
          } 
         } 
        } 
    
        return sectionTitle 
    } 
    
  5. 在构建您的NSFetchedResultsController,调用与初始化"daySectionIdentifier"作为sectionNameKeyPath参数。
  6. 将您的NSFetchedResultsController的排序描述符设置为您实体的普通旧"date"属性。重要的是,基于"date"的排序顺序将与基于我们刚刚构建的部分标识符的排序顺序一致。

您现在应该已将表格视图按天分组(例如“2017年2月6日”),并按细粒度日期进行排序。

相关问题