如何复制iPhone最近通话时间标签

时间:2011-11-29 03:12:44

标签: ios sorting nsdate uitableview

假设我的UITableView由一系列X量的NSDates提供。我如何对它们进行排序,以便UITableView模仿iPhone上的Phone应用程序,但是在某种程度上,UITableView中每天都有一个由数组中的日期(或多个日期)表示的部分?

编辑突破!为了弄清楚我需要多少部分,我用这个:

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

2 个答案:

答案 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的机会。

答案 1 :(得分:0)

我真的认为你应该使用核心数据和NSFetchResultController它会为你做的工作 -

要解释所有需要的步骤,但要排成一行 -

  1. 将核心数据添加到您的应用中。
  2. 创建一个类和一个核心数据实体,例如(日期)。
  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];
         }
    
  8. 你可以在这里看到苹果的一个例子: http://developer.apple.com/library/ios/#samplecode/DateSectionTitles/Introduction/Intro.html

    希望它会有所帮助