2012-10-17 58 views
0

我有兩種類型的事件存儲在我的核心數據棧中,每個事件都有一個時間戳。我很感興趣,如果有一個很好的方法來顯示這些記錄在UITableView與部分,其中每個部分是任意長(一天,一週等)iPhone核心數據如何添加日期部分與時間戳事件?

有沒有辦法將一個核心數據對象的時間戳轉換爲一個節標題,四捨五入的時間?

所以我們會得到:

October 5 < section title 
    Record 1 < records displayed in the section 
    Record 2 
    Record 3 

    October 6 
    Record 4 

    October 7 
    Record 5 
    ... 


-OR- 
Week 1 
Record 1 
Record 2 

Week 2 
Record 3 
... 

這裏是我目前使用來實現這一目標是什麼,但它是有限的每個部分是一個天。

但讓我說我沒有想過這個要求,並有一個只有時間戳事件的列表。我怎樣才能把它們分成幾個部分?

//the method used to convert a date into a number to store with the event 
    -(int)getDateIDFromDate:(NSDate*)date 
    { 
     int gmtOffset = [[NSTimeZone localTimeZone] secondsFromGMT]; 
     int dateID =([date timeIntervalSinceReferenceDate]+gmtOffset)/86400; 
     return dateID; 
    } 


    //when inserting a record, the number is saved 
    newManagedObject.dayID = [NSNumber numberWithInt:[self getDateIDFromDate:date]]; 


    //when retrieving, the number is used as a section key path 
    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"dayID" cacheName:@"Day"]; 


//the number gets converted back into the date. 
    - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { 
     // Display the authors' names as section headings. 
     // return [[[dataManager.dreamEventsController sections] objectAtIndex:section] name]; 

     NSString* dayIndex = [[[dataManager.fetchedResultsController sections] objectAtIndex:section] name]; 
     int dayFromReferenceDate = dayIndex.intValue; 
     return [dataManager.sectionDateFormatter stringFromDate:[NSDate dateWithTimeIntervalSinceReferenceDate:(dayFromReferenceDate+1)*86400]]; 



    } 

回答

1

添加(冗餘)數據僅用於顯示目的應始終是最後的手段。

在稍微類似的情況下,我只是將一個類別添加到CoreData對象,例如,

-(NSString*)firstLetter 
{ 
    NSString *title = self.title; 
    if ([title length] == 0) return @"?"; 
    return [title substringToIndex:1]; 
} 

然後我就用這個作爲sectionNameKeyPath及一切都只是同在一個正常的情況。

就你而言,這個類別會稍微詳細些,但總體概要可能是相同的。而且部分名稱會變得不穩定的事實也應該記住。

一個棘手的(/醜陋的)部分將傳達當前的分區設置的類別。一些全局或靜態變量可以有效地完成這項工作。

+0

這是一個好主意。如果我理解正確,firstLetter方法將包含我當前用於將日期轉換爲dayID並返回的邏輯。 –

+0

我試過了,並沒有奏效。 NSFetchedResultsController的第一個排序鍵必須與節名稱鍵路徑相同,並且沒有這樣的鍵路徑。如果沒有這個,應用程序會崩潰,因爲找不到某個節中的行。我嘗試添加一個瞬態屬性,但不認爲我是正確的,因爲它不可能用作第一個排序描述符。 –

+0

@AlexStone *「必須相同」*這不是一個硬性要求。它必須根據段名稱keypath進行排序,但不能*使用段名稱keypath。即只需使用實際的日期字段進行排序,然後使用添加的字段添加部分。 – mvds

1

最好的方法是將一個瞬態屬性添加到您的託管對象模型。在該屬性的訪問器中,返回標準化的NSDate並截斷時間(可以使用NSDateComponents執行此操作)。然後,當需要獲取這些對象時,請將.. sectionNameKeyPath:設置爲該瞬態屬性。

更新:比方說,你的NSManagedObject子類有一個短暫的屬性monthOfTheYear

- (NSNumber*)monthOfTheYear 
{ 
    [self willAccessValueForKey:@"monthOfTheYear"]; 

    NSDateComponent *dateComponent = [cachedCalendar components:NSMonthCalendarUnit fromDate:self.timestamp]; // cachedCalendar is a NSCalendar instance 

    [self didAccessValueForKey:@"monthOfTheYear"]; 
    return [NSNumber numberWithInteger:dateComponent.month]; // or a normalized number that takes consideration of the year too 
} 

我們不創建一個NSString瞬態屬性直接,因爲這會搞亂你的排序(和你失去的多語言支持) 。 willAccessValueForKey:didAccessValueForKey:很重要。你應該閱讀更多關於他們的文件。

然後當它的時間來顯示章節標題:

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section 
{ 
    NSInteger monthNumber = // Get the monthOfTheYear value from the first NSManagedObject in this section. 
    return [[cachedDateFormatter monthSymbols] objectAtIndex:(monthNumber-1)]; // cachedDateFormatter is a NSDateFormatter instance 

} 
+0

你可以添加一些關於如何爲這個屬性創建一個訪問器的細節?我試着把它放在覈心數據子類中,在@dynamic titleForSection之後; - (NSString *)titleForSection {...},但這不起作用 –

+0

我添加了一些示例代碼。 –

0

燮兄弟!我的建議是使用NSDateFormatter

這是鏈接蘋果文檔:NSDateFormatter

我會在managedObject,你有時間戳添加類別,

@interface MyManagedobject (ReadableTimestamp) 
    -(NSString *)formatedStringFromTimestamp; 
@end 

@implementation MyManagedobject (ReadableTimestamp) 
    -(NSString *)formatedStringFromTimestamp{ 
     //TODO: Here you apply all your fancy format, I'm just using the default 
     NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; 
     [formatter setFormatterBehavior:NSDateFormatterBehavior10_4]; 
     [formatter setDateStyle:dateStyle]; 
     [formatter setTimeStyle:timeStyle]; 
     NSString *result = [formatter stringForObjectValue:self.timestamp]; 
     return result; 
    } 

@end 

我希望這可以幫助,美好時光。

如果你是某種優化怪胎(比如我自己),你可以將你的timeFormatter定義爲靜態的,這樣你就不需要每次都構建它。