假设我的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];
}
答案 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它会为你做的工作 -
要解释所有需要的步骤,但要排成一行 -
您需要将“date”属性作为 sectionNameKeyPath 传递给您的获取操作,这将通知获取结果控制器您希望按日期对这些部分进行排序。
aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:YourContext sectionNameKeyPath:@"date" cacheName:nil];
然后你必须将这些功能添加到你的表视图中,他们将为你完成这项工作:
- (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
希望它会有所帮助