einen sectionHeader/footer anzupassen, ist an sich keine schwierigkeit, da es hierfür bequeme delegate-methoden des UITableViewDelegates gibt.
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section;
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section;
mein problem war, dass ich die daten des NSFetchedResultControllers nach einem wert gruppieren wollte, der sich selbst nicht als property im model befindet.
d.h. ich hatte z.b ein object mit einer startzeit, einer endzeit und einem beschreibungstext als modelobjekt. gruppieren wollte ich die daten im der UITableView jedoch nach dem start__tag__, an dem die objekte angelegt wurden, und nicht nach der start/endzeit (da diese ja von objekt zu objekt immer unterschiedlich ist und somit keine gruppierung zustande kommt). d.h. ich wollte die zeit ignorieren und einfach nur nach dem datum selbst gruppieren.
und da fing mein problem an :)
nehmen wir zuerst mal folgendes objekt als modelgrundlage für den NSFechtedResultController an.
@interface TestObject : NSManagedObject {
}
@property (nonatomic, retain) NSDate * starttime;
@property (nonatomic, retain) NSDate * endtime;
@property (nonatomic, retain) NSString * text;
@end
weiter nehmen wir an, wir wollen ganz simpel nach dem text gruppieren. so müssen wir lediglich bei der erstellung des NSFetchedResultControllers auf den __sectionNameKeyPath__ achten. bei default-initialisierungen kann der wert einfach NIL sein. so werden keine sections angelegt, also nicht gruppiert. will man jedoch nach einem property des modelobjekts gruppieren, gibt man einfach dessen namen an.
da wir als beispiel nach dem text gruppieren wollen, würde die initialisierung des NSFetchedResultControllers wie folgt aussehen:
NSFetchedResultsController *aFetchedResultsController =
[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:self.managedObjectContext
sectionNameKeyPath:@”text”
cacheName:@”Root”];
wenn man nun noch die tableView:tableView titleForHeaderInSection:section implementiert, werden die sections mit dem wert aus dem text-property des TestObject-objekts benannt.
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
id sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section]; return [sectionInfo name];
}
soweit sogut. nun wollen wir aber keinen direkten propertywert als gruppierungsgrundlage verwenden, sondern wie oben erwähnt z.b. nur das datum der starttime, damit man die objekte nach tagen gruppiert auffindet.
hierfür muss man schon etwas in die trickkiste greifen, wie ich meine. zumindest lag die lösung für mich nicht sofort auf der hand.
also zuerst gehen wir her und erweitern unser modelobjekt um das property day in der TestObject.h datei. das is deshalb ein string, da wir die datums/zeitinformation des NSDate objekts nicht brauchen, sondern nur eine kurze stringrepräsentation des datums. damit hat auch der NSFetchResultsController kein problem, wenn er danach gruppieren soll.
@property (nonatomic, retain) NSString * day;
für dieses property day müssen wir nun noch eine methoden verfassen, damit es auch mit einem wert belegt wird. das passiert in der TestObject.m datei. in diesem beispiel wird einfach nur der datumswert aus der starttime geholt und die zeit dabei völlig ignoriert. raus kommt dabei ein string wie “14. Aug. 2011”. also ein kurzer datumsstring, der auch einfach vergleichbar ist.
- (NSString *) day {
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
[dateFormatter setTimeStyle:NSDateFormatterNoStyle];
NSString *formattedDateString = [dateFormatter stringFromDate:self.starttime];
return formattedDateString;
}
nun haben wir also unser model um einen neuen pseudowert erweitert. d.h. es sollte nun auch ganz einfach möglich sein, danach zu gruppieren :) und was tun wir, damit nach unserem neuen property day gruppiert wird? klar! ganz einfach den sectionNameKeyPath beim initialisieren des NSFetchResultController anpassen. sieht dann aus wie folgt:
NSFetchedResultsController *aFetchedResultsController =
[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext
sectionNameKeyPath:@”day”
cacheName:@”Root”];
da wird bereits die tableView:tableView titleForHeaderInSection:section implementiert haben, sollte die UITableView nun tun, wie ihr befohlen wurde und die TestObject objekte nach dem datum der starttime zu gruppieren und zusätzlich dieses datum auch als sectionheader benutzen.
voila :) wieder ein problem gelöst!