我之前发布过类似的问题,请查看此链接UITableView sections are not ordered as expected 我需要解决的问题如下: 我有一个带定制部分的tableView。节标题取自在名为ToDoItem的NSManagegObject子类中定义的瞬态属性。 transient属性称为sectionIdentifier。在我的tableView viewController中,我有一个带有两个NSSortDescriptors的fetchedResultsController来命令对象:
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc]initWithKey:@"todoDueDate" ascending:YES];
NSSortDescriptor *sortDescriptor1 = [[NSSortDescriptor alloc]initWithKey:@"todoName" ascending:YES];
考虑到瞬态属性不能在NSSortDescriptor中用作initWithKey值,现在根据todoDueDate的属性值而不是sectionIdentifier值(这应该是我的预期顺序)对这些节进行排序。 我把下面的代码形式放在classer下面,sectionIdentifier的第一个定义是ToDoItem类,第二个是tableView vieController类。
-(NSString *)sectionIdentifier{
[self willAccessValueForKey:@"sectionIdentifier"];
NSString *tmp = [self primitiveValueForKey:@"sectionIdentifier"];
[self didAccessValueForKey:@"sectionIdentifier"];
if ([self.isSomeDay isEqualToString:@"noissomeday"]){//SI NO ES SOMEDAY
if (!tmp){
//NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSInteger comps = (NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit);
NSDate *today = [NSDate date];
NSDate *date = self.todoDueDate;
NSDateComponents *date1Components = [calendar components:comps
fromDate: today];
NSDateComponents *date2Components = [calendar components:comps
fromDate: date];
today = [calendar dateFromComponents:date1Components];
date = [calendar dateFromComponents:date2Components];
NSInteger daysAfterToday = [calendar components:NSDayCalendarUnit
fromDate:today toDate:date options:0].day;
// NSString *section;
if (daysAfterToday < 0) {
tmp = @"0";
} else if (daysAfterToday == 0) {
tmp = @"1";
} else if (daysAfterToday > 0 && daysAfterToday < 2) {
tmp = @"2";
} else {
tmp = @"3";
}
NSLog(@"TODAY = %@", today);
NSLog(@"DATE = %@", date);
NSLog(@"DAYS AFTER TODAY = %ld",(long)daysAfterToday);
[self setPrimitiveValue:tmp forKey:@"sectionIdentifier"];
}
}
//no is someday
else if ([self.isSomeDay isEqualToString:@"issomeday"]){
tmp = @"4";
}
NSLog(@"Tmp= %@",tmp);
return tmp;
}
这是我想要获得的部分顺序:
1. OVERDUE, sectionIdentifier = 0
2. TODAY, sectionIdentifier = 1
3. TOMORROW, sectionIdentifier = 2
4. UPCOMING, sectionIdentifier = 3
5. SOMEDAY, sectionIdentifier = 4
ToDoItemsTableViewController.m
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
if (tableView == self.searchDisplayController.searchResultsTableView)
{
return 1;
}
else
{
return [[self.fetchedResultsController sections]count];
}
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
if (tableView == self.searchDisplayController.searchResultsTableView)
{
return [self.searchResults count];
}
else {
id<NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections]objectAtIndex:section];
return [sectionInfo numberOfObjects];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// Configure the cell...
ToDoItem *toDoItem = nil;
if (tableView == self.searchDisplayController.searchResultsTableView)
{
if (cell==nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
cell.accessoryType=UITableViewCellAccessoryDisclosureIndicator;
}
NSLog(@"Configuring cell to show search results");
toDoItem = [self.searchResults objectAtIndex:indexPath.row];
cell.textLabel.text = toDoItem.todoName;
NSDate *fechaToDO = toDoItem.todoDueDate;
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setDateFormat:@"EEEE, dd MMMM YYYY"];
NSString *fechaToDo = [dateFormatter stringFromDate:fechaToDO];
NSString *valorSomeDay = toDoItem.isSomeDay;
if ([valorSomeDay isEqualToString:@"issomeday"]){
cell.detailTextLabel.text = @"Someday";
}
else {
cell.detailTextLabel.text = fechaToDo;
}
}
else
{
ToDoItem *todoitem = [self.fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = todoitem.todoName;
NSDate *fechaToDO = todoitem.todoDueDate;
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setDateFormat:@"EEEE, dd MMMM YYYY"];
NSString *fechaToDo = [dateFormatter stringFromDate:fechaToDO];
NSString *valorSomeDay = todoitem.isSomeDay;
if ([valorSomeDay isEqualToString:@"issomeday"]){
cell.detailTextLabel.text = @"Someday";
}
else {
cell.detailTextLabel.text = fechaToDo;
}
}
return cell;
}
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
static NSString *header = @"customHeader";
UITableViewHeaderFooterView *vHeader;
vHeader = [tableView dequeueReusableHeaderFooterViewWithIdentifier:header];
if (!vHeader) {
vHeader = [[UITableViewHeaderFooterView alloc] initWithReuseIdentifier:header];
vHeader.textLabel.backgroundColor = [UIColor redColor];
vHeader.textLabel.textColor = [UIColor whiteColor];
vHeader.contentView.backgroundColor = [UIColor redColor];
}
if (section == 0) {
vHeader.textLabel.backgroundColor = [UIColor redColor];
vHeader.textLabel.textColor = [UIColor whiteColor];
vHeader.contentView.backgroundColor = [UIColor redColor];
}
else if (section == 1) {
vHeader.textLabel.backgroundColor = [UIColor orangeColor];
vHeader.textLabel.textColor = [UIColor blueColor];
vHeader.contentView.backgroundColor = [UIColor orangeColor];
}
else if (section == 2) {
vHeader.textLabel.backgroundColor = [UIColor greenColor];
vHeader.textLabel.textColor = [UIColor whiteColor];
vHeader.contentView.backgroundColor = [UIColor greenColor];
}
else if (section == 3) {
vHeader.textLabel.backgroundColor = [UIColor greenColor];
vHeader.textLabel.textColor = [UIColor whiteColor];
vHeader.contentView.backgroundColor = [UIColor greenColor];
}
else if (section == 4) {
vHeader.textLabel.backgroundColor = [UIColor blueColor];
vHeader.textLabel.textColor = [UIColor whiteColor];
vHeader.contentView.backgroundColor = [UIColor blueColor];
}
vHeader.textLabel.text = [self tableView:tableView titleForHeaderInSection:section];
return vHeader;
}
-(NSString*)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section{
if (tableView == self.searchDisplayController.searchResultsTableView){
NSString *valor = [NSString stringWithFormat:@"S E A R C H R E S U L T S (%d)",[self.searchResults count]];
return valor;
}
else {
id <NSFetchedResultsSectionInfo> theSection = [[self.fetchedResultsController sections]objectAtIndex:section];
NSString *sectionname = [theSection name];
if ([sectionname isEqualToString:@"0"]){
NSString *valor = [NSString stringWithFormat:@"O V E R D U E (%d)", [self.tableView
numberOfRowsInSection:section]];
return valor;
}
else if ([sectionname isEqualToString:@"1"]){
NSString *valor = [NSString stringWithFormat:@"T O D A Y (%d)", [self.tableView
numberOfRowsInSection:section]];
return valor;
}
else if ([sectionname isEqualToString:@"2"]){
NSString *valor = [NSString stringWithFormat:@"T O M O R R O W (%d)", [self.tableView
numberOfRowsInSection:section]];
return valor;
}
else if ([sectionname isEqualToString:@"3"]){
NSString *valor = [NSString stringWithFormat:@"U P C O M I N G (%d)", [self.tableView
numberOfRowsInSection:section]];
return valor;
}
else if ([sectionname isEqualToString:@"4"]){
NSString *valor = [NSString stringWithFormat:@"S O M E D A Y (%d)", [self.tableView
numberOfRowsInSection:section]];
return valor;
}
if ([[self.fetchedResultsController sections]count]>0){
id<NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections]objectAtIndex:section];
return [sectionInfo name];
}
else{
return nil;
}
}
}
#pragma mark - Fetched Results Controller Section
-(NSFetchedResultsController*)fetchedResultsController{
if (_fetchedResultsController != nil){
return _fetchedResultsController;
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc]init];
NSManagedObjectContext *context = self.managedObjectContext;
NSEntityDescription *entity = [NSEntityDescription entityForName:@"ToDoItem" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc]initWithKey:@"todoDueDate" ascending:YES];
NSSortDescriptor *sortDescriptor1 = [[NSSortDescriptor alloc]initWithKey:@"todoName" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc]initWithObjects:sortDescriptor,sortDescriptor1, nil];
fetchRequest.sortDescriptors = sortDescriptors;
_fetchedResultsController = [[NSFetchedResultsController alloc]initWithFetchRequest:fetchRequest managedObjectContext:context sectionNameKeyPath:@"sectionIdentifier" cacheName:nil];
_fetchedResultsController.delegate = self;
return _fetchedResultsController;
}
答案 0 :(得分:1)
我假设“SOMEDAY”条目是todoDueDate
未指定的条目。
问题是第一个排序描述符“todoDueDate”必须兼容
部分标识符。因此,您不能使用两个单独的属性todoDueDate
和
isSomeDay
部分。
因此,您应该分配这些对象,而不是使用单独的属性isSomeDay
一个远未来的价值:
self.todoDueDate = [NSDate distantFuture];
以便在所有其他对象之后自动排序。
然后你可以在sectionIdentifier
方法中执行类似的操作:
if ([self.todoDueDate isEqualToDate:[NSDate distantFuture]) {
tmp = @"4";
} else {
// ... your other checks for overdue, today, tomorrow, upcoming
}
同样在viewForHeaderInSection
中,您不应该检查部分编号,
但对于部分名称(“0”,“1”,......)。原因是某个部分可能是空的:
如果没有“OVERDUE”对象,那么“TODAY”就是#0部分。
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
id <NSFetchedResultsSectionInfo> theSection = [[self.fetchedResultsController sections] objectAtIndex:section];
NSString *tmp = [theSection name];
if ([tmp isEqualToString:@"0"]) {
// OVERDUE
} else if ([tmp isEqualToString:@"1"]) {
// TODAY
} else
// and so on ...
}