一个 NSFetchedResultsController ,日期为sectionNameKeyPath

发布于 2024-10-07 07:59:37 字数 513 浏览 1 评论 0原文

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

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

我为每个对象获得一个新部分,因为此代码也根据秒对日期进行分组。但我想要一个按日期分组的对象列表,但仅根据日、月和年分组。这可能吗?如何实现?

非常感谢您的帮助!! ;)

I develop an application which uses Core Data. In one UITableView, I want to display a list of my entities, sorted by the saved date of the objects. When I do this:

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

I get for each object a new section because this code groups the dates according to the seconds, too. But I want a list of the objects, grouped by date, but only according to the day, month and year. Is it possible and how?

Thank you very much for your help!! ;)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

烂柯人 2024-10-14 07:59:37

这应该对你有用:

- (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 值。

简而言之,对于具有 fooDatefooDateTransient 属性的 foo 对象,您将:

  1. 获取您的 foo.fooDate 属性

  2. 使用上面的代码(或类似代码)对其进行转换,并将 NSDate 结果分配给 foo.fooDateTransient

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

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

祝你好运,
罗格

This should do the trick for you:

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

[EDIT]

Jus saw your comment and for what you are trying to achieve, you could create a transient NSDate attribute (non persistent) that is formatted in a similar way to the above code (i.e. without H:mm:ss ZZZZ) and use that attribute as your sectionNameKeyPath value.

So in a nutshell for a foo object, with fooDate and fooDateTransient attributes, you would:

  1. Get your foo.fooDate attribute

  2. Transform it using the code above (or similar) and assign the NSDate result to foo.fooDateTransient

  3. Use fooDateTransient as your sectionNameKeyPath when creating the fetchedResultsController object.

PS: I haven't tested this myself but should be worth a shot!

Good luck,
Rog

喵星人汪星人 2024-10-14 07:59:37

查看: http ://developer.apple.com/library/ios/#samplecode/DateSectionTitles/Introduction/Intro.html#//apple_ref/doc/uid/DTS40009939

它适用于月份和年份,但很容易制作它适用于日、月和年。

Check out: http://developer.apple.com/library/ios/#samplecode/DateSectionTitles/Introduction/Intro.html#//apple_ref/doc/uid/DTS40009939

It works with month and year, but it's quite easy to make it work with day, month and year.

一个人练习一个人 2024-10-14 07:59:37

以下是按日期排序的 Swift 3 解决方案,但具有与各个日期相对应的部分标题。

  1. 将名为 daySectionIdentifier 的瞬态属性添加到核心数据中的实体。
  2. 重新生成您的 NSManagedObject 子类。删除可能在 Entity+CoreDataProperties.swift 中生成的 daySectionIdentifier 属性。
  3. Entity+CoreDataClass.swift 文件中,为 daySectionIdentifier 添加以下 getter:

    // 用于将表分组为基于部分的临时属性
    // 实体日期当天。允许 NSFetchedResultsController
    // 按日期排序,但也将日期显示为部分标题。
    // - 构造一个格式为“YYYYMMDD”的字符串,其中 YYYY 是年份,
    // MM 是月份,DD 是日期(均为整数)。
    
    公共 var daySectionIdentifier:字符串? {
        让 currentCalendar = Calendar.current
        self.willAccessValue(forKey: "daySectionIdentifier")
        var 节标识符 = ""
        如果让 date = self.date 为?日期 {
            让 day = currentCalendar.component(.day, from: date)
            让月份 = currentCalendar.component(.month, from: date)
            让年份 = currentCalendar.component(.year, from: date)
    
            // 根据年、月、日构造整数。转换为字符串。
            sectionIdentifier = "\(年 * 10000 + 月 * 100 + 日)"
        }
        self.didAccessValue(forKey: "daySectionIdentifier")
    
        返回节标识符
    }
    
  4. 在您的 UITableViewController 中> 实现,添加以下方法:

    覆盖 func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) ->细绳? {
        varsectionTitle:字符串?
        如果让sectionIdentifier = fetchedResultsController.sections?[section].name {
            if let numericSection = Int(sectionIdentifier) {
                // 将 numericSection 解析为其年/月/日组件。
                让年份 = numericSection / 10000
                让月份 = (numericSection / 100) % 100
                让日 = numericSection % 100
    
                // 根据这些组件重建日期。
                var 组件 = DateComponents()
                组件.日历 = 日历.当前
                组件.day = 天
                组件.月份 = 月份
                组件.year = 年份
    
                // 使用该日期设置章节标题
                如果让日期=组件.日期{
                    sectionTitle = DateFormatter.localizedString(from: date, dateStyle: .medium, timeStyle: .none)
                }
            }
        }
    
        返回章节标题
    }
    
  5. 在构造 NSFetchedResultsController 时,使用 "daySectionIdentifier" 调用初始化程序> 作为 sectionNameKeyPath 参数。
  6. 将您的 NSFetchedResultsController 的排序描述符设置为实体的普通旧 “date” 属性。重要的是,基于“date”的排序顺序将与基于我们刚刚构造的节标识符的排序顺序一致。

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

The following is a Swift 3 solution to sort by date but have section titles corresponding to individual days.

  1. Add a transient property called daySectionIdentifier to your entity in Core Data.
  2. Regenerate your NSManagedObject subclass. Delete the property for daySectionIdentifier that may get generated in Entity+CoreDataProperties.swift.
  3. To the Entity+CoreDataClass.swift file, add the following getter for 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. In your UITableViewController implementation, add the following method:

    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. When constructing your NSFetchedResultsController, call the initializer with "daySectionIdentifier" as the sectionNameKeyPath parameter.
  6. Set your NSFetchedResultsController's sort descriptor to your entity's plain old "date" attribute. Importantly, the sort order based on "date" will be consistent with the sort order based on the section identifier that we just constructed.

You should now have your table view grouped into sections by day (e.g., "Feb 6, 2017"), and sorted by fine-grained date.

尸血腥色 2024-10-14 07:59:37

我认为这样会更好。

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

I think this would be better.

- (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;
}
锦上情书 2024-10-14 07:59:37

当遇到同样的问题时,我使用了@BoltClock's a Unicorn 和@Rog's 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;
}

I used @BoltClock's a Unicorn and @Rog's anwser when having the same issue.
Simply added a transient NSString *sectionTitle to my managed object, used @"sectionTitle" as sectionNameKeyPath and created a custom getter like so:

-(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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文