2011-11-29 128 views
0

假設我的UITableView由一個X數量的NSDates數組提供。我怎樣才能對它們進行排序,以便UITableView模仿iPhone上的Phone應用程序,但這樣做是爲了讓UITableView中的每一天有一段由數組中的日期(或多個日期)表示的部分?如何複製iPhone最近呼叫通話時間標籤

編輯:突破!爲了弄清楚有多少部分需要,我用這個:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 
    NSArray* array = [[NSUserDefaults standardUserDefaults] objectForKey:@"mapSaveDataKey"]; 
    NSMutableArray* dateStrings = [[NSMutableArray alloc] init]; 
    for(NSArray* innerArray in array) 
     [dateStrings addObject:[dateFormatter stringFromDate:[innerArray objectAtIndex:13]]]; 

    NSArray *cleanedArray = [[NSSet setWithArray:dateStrings] allObjects]; 

    return [cleanedArray count]; 
} 

通過採取這些格式的使用NSDateFormatter NSDates使用這些設置dateStrings的數組:

[dateFormatter setTimeStyle:NSDateFormatterNoStyle]; 
[dateFormatter setDateStyle:NSDateFormatterMediumStyle]; 
[dateFormatter setDoesRelativeDateFormatting:YES]; 

我可以得到一個列表不管時間如何,來自同一天的每個字符串都是相同的。然後,我可以使用NSSet獲取不包含重複項的相同字符串的數組,並且該數組的數量是我需要的部分的數量。大。

現在到了困難的部分:我如何獲取該字符串數組(或原始NSDates數組)並找出每天有多少重複數據,並使用該信息來決定需要多少行在UITableView的每個部分?爲了讓事情變得更加困難,他們需要從最近的到最老的。 (還有一個問題是確定哪些單元需要在哪個部分進行,但可以在以後找到)

解決了,這得益於Ole Begemann提供的雄辯解決方案。 +100你 我用這個循環弄清楚當我陣列我要開始爲每個部分:

int offset = 0; 
for(int idx = 0; idx < [tableViewOutlet numberOfSections]; idx++) { 
    if(idx == indexPath.section) 
     break; 
    offset += [tableViewOutlet numberOfRowsInSection:idx]; 
} 
+0

這裏太晚了,我不想進入這個。但爲了讓你開始看看[日曆計算](http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/DatesAndTimes/Articles/dtCalendricalCalculations.html)文檔。通過使用秒來計算日期是passè。一旦你能夠開始將你的數組分成日期,你會發現處理這個更容易。 – Abizern

+0

感謝您的鏈接,它幫助了很多!請參閱我的編輯... –

回答

2

就我個人而言,不使用日期格式化程序。如果你有更多的「數值」(日期)可用,處理字符串感覺有點「髒」。使用NSDateComponents,將日期與NSDate的時間組分分開也很容易。下面的示例代碼很長,但它應該很容易理解。給定一個(樣本)NSDate對象(在dates變量中),它將生成一個sections字典。

字典的鍵是NSDate表示某一天的實例(它們的時間分量在所使用的日曆的時區中是微不足道的)。字典的值是包含屬於某個部分(排序)的實際日期的數組。您應該可以使用該信息填充表格視圖。

// Sample data: an array of dates 
NSArray *dates = [NSArray arrayWithObjects: 
    [NSDate dateWithTimeIntervalSince1970:1322756697], 
    [NSDate dateWithTimeIntervalSince1970:1322727896], 
    [NSDate dateWithTimeIntervalSince1970:1322699096], 
    [NSDate dateWithTimeIntervalSince1970:1322695496], 
    [NSDate dateWithTimeIntervalSince1970:1322677496], 
    [NSDate dateWithTimeIntervalSince1970:1322504696], 
    nil]; 

// First we sort the dates 
NSArray *sortedDates = [dates sortedArrayUsingSelector:@selector(compare:)]; 

NSCalendar *calendar = [NSCalendar currentCalendar]; 
NSTimeZone *utc = [NSTimeZone timeZoneForSecondsFromGMT:0]; 
[calendar setTimeZone:utc]; 

// Populate the sections dictionary 
NSMutableDictionary *sections = [NSMutableDictionary dictionary]; 
for (NSDate *date in sortedDates) { 
    NSDateComponents *dateComps = [calendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:date]; 
    NSDate *dateRepresentingThisDay = [calendar dateFromComponents:dateComps]; 
    NSMutableArray *datesOnThisDay = [sections objectForKey:dateRepresentingThisDay]; 
    if (datesOnThisDay == nil) { 
     // This day is new. 
     // Create an empty array and add it to the dictionary under this day as key. 
     datesOnThisDay = [NSMutableArray array]; 
     [sections setObject:datesOnThisDay forKey:dateRepresentingThisDay]; 
    } 
    [datesOnThisDay addObject:date]; 
} 

// Output the result  
NSLog(@"Found %u sections.", [sections count]); 
NSArray *sortedDays = [[sections allKeys] sortedArrayUsingSelector:@selector(compare:)]; 
for (NSDate *day in sortedDays) { 
    NSLog(@"Section: %@", day); 
    NSArray *datesOnThisDay = [sections objectForKey:day]; 
    for (NSDate *date in datesOnThisDay) { 
     NSLog(@"-- Entry: %@", date); 
    } 
} 

編輯:我把這個問題作爲寫一個blog post about this problem的機會。

+0

+1用於處理代表感覺髒的日期的字符串。我確切地知道你的意思(並且有1001個SO問題,人們只是做錯了)。這也是一個非常好用的字典。 – jrturton

+0

稍微調整一下,我已經中途實施了這個解決方案,到目前爲止它工作得很好(給我一個正確的行數,並且正確的章節標題),但現在我必須學習英語測試所以我不得不在明天或週末完成另一半。好的解決方案 –

+1

哇 - 漂亮的實現。貫穿始終。這次真是萬分感謝!我在問題中添加了一小部分,以使其發揮作用。 –

0

我真的覺得你應該使用核心數據和NSFetchResultController它會做LL爲您的工作 -

這將是時間去解釋所有需要的步驟,但在出線 -

  1. 核心數據添加到您的應用程序。
  2. 創建一個類和一個名爲Core Data的實體,例如(Date)。
  3. 設置實體的屬性(如 - 「text」,「date」等)。
  4. 迭代您的陣列和陣列中的每個對象,將持有的對象的日期創建一個實體。
  5. (你可以在應用程序的午餐或者是適合於您的應用程序的任何時間做到這一點)現在您已準備好實體,您可以使用NSFetchResultController設置您的表格視圖。
  6. 您將需要將「date」屬性傳遞給您的獲取操作,因爲sectionNameKeyPath這將通知獲取結果控制器您要按日期對節進行排序。

    aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:YourContext sectionNameKeyPath:@"date" cacheName:nil]; 
    
  7. ,那麼你將不得不這些功能添加到您的表視圖,他們會爲你做這項工作:

    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 
         NSInteger count = [[[self fetchedResultsController] sections] count]; 
         return count; 
        } 
    
        - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 
         NSInteger numberOfRows = 0; 
    
         if ([[[self fetchedResultsController] sections] count] > 0) { 
         id <NSFetchedResultsSectionInfo> sectionInfo = [[[self fetchedResultsController] sections] objectAtIndex:section]; 
         numberOfRows = [sectionInfo numberOfObjects]; 
         } 
    
        return numberOfRows; 
        } 
    
        - (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView { 
         return [[self fetchedResultsController] sectionIndexTitles]; 
        } 
    
        - (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index { 
         return [[self fetchedResultsController] sectionForSectionIndexTitle:[title capitalizedString] atIndex:index]; 
        } 
    
        - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { 
         id <NSFetchedResultsSectionInfo> sectionInfo = [[[self fetchedResultsController] sections] objectAtIndex:section]; 
         return [sectionInfo name]; 
        } 
    

你可以從這裏蘋果看一個例子: http://developer.apple.com/library/ios/#samplecode/DateSectionTitles/Introduction/Intro.html

希望它能幫到