簡體   English   中英

一個NSFetchedResultsController,日期為sectionNameKeyPath

[英]A NSFetchedResultsController with date as sectionNameKeyPath

我開發了一個使用Core Data的應用程序。 在一個UITableView中,我想顯示我的實體列表,按照對象的保存日期排序。 當我這樣做:

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

我為每個對象添加了一個新部分,因為此代碼也根據秒數對日期進行分組。 但我想要一個按日期分組的對象列表,但只根據日,月和年。 有可能嗎?怎么樣?

非常感謝您的幫助!! ;)

這應該是你的訣竅:

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

[編輯]

Jus看到了你的評論以及你想要實現的目標,你可以創建一個瞬態NSDate屬性(非持久性),其格式與上面的代碼類似(即沒有H:mm:ss ZZZZ)並使用該屬性作為你的sectionNameKeyPath值。

因此簡而言之,對於foo對象,使用fooDatefooDateTransient屬性,您將:

  1. 獲取您的foo.fooDate屬性

  2. 使用上面的代碼(或類似代碼)對其進行轉換,並將NSDate結果分配給foo.fooDateTransient

  3. 使用fooDateTransient為您sectionNameKeyPath創建時fetchedResultsController對象。

PS:我自己沒有測試過,但值得一試!

祝你好運,羅格

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

它適用於月份和年份,但它很容易使它適用於日,月和年。

以下是Swift 3解決方案,按日期排序,但部分標題對應於各個日期。

  1. 將名為daySectionIdentifier的瞬態屬性添加到Core Data中的實體。
  2. 重新生成NSManagedObject子類。 刪除該屬性daySectionIdentifier可以在獲取生成Entity+CoreDataProperties.swift
  3. Entity+CoreDataClass.swift文件中,為daySectionIdentifier添加以下getter:

     // 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日”),並按細粒度日期排序。

當遇到同樣的問題時,我使用了@ 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;
}

我認為這會更好。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM