在我的tableView中,我修复了部分并修复了部分标题。这是我的部分要求的代码:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 6;
}
+ (NSString*) titleForHeaderForSection:(int) section
{
switch (section)
{
case 0 : return @"Overdue";
case 1 : return @"Today";
case 2 : return @"Tomorrow";
case 3 : return @"Upcoming";
case 4 : return @"Someday";
case 5 : return @"Completed";
//default : return [NSString stringWithFormat:@"Section no. %i",section + 1];
}
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return [CollapsableTableViewViewController titleForHeaderForSection:section];
}
这部分工作正常,但现在我想用核心数据对象填充这些部分。 对于这部分,在获取结果之前,我有以下代码:
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSError *error = nil;
if (![[self fetchedResultsController] performFetch:&error])
{
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
switch (section)
{
case 2 : return 3;
case 3 : return 30;
default : return 3;
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell.
switch (indexPath.row)
{
case 0 : cell.textLabel.text = @"First Cell"; break;
case 1 : cell.textLabel.text = @"Second Cell"; break;
case 2 : cell.textLabel.text = @"Third Cell"; break;
case 3 : cell.textLabel.text = @"Fourth Cell"; break;
case 4 : cell.textLabel.text = @"Fifth Cell"; break;
case 5 : cell.textLabel.text = @"Sixth Cell"; break;
case 6 : cell.textLabel.text = @"Seventh Cell"; break;
case 7 : cell.textLabel.text = @"Eighth Cell"; break;
default : cell.textLabel.text = [NSString stringWithFormat:@"Cell %i",indexPath.row + 1];
}
//cell.detailTextLabel.text = ...;
return cell;
}
这也很好地填充了各个部分...但我真正的要求是使用来自核心数据实体的对象填充这些部分。这意味着,我必须替换这些行:
switch (section)
{
case 2 : return 3;
case 3 : return 30;
default : return 3;
}
使用其他代码行以获取节中的实际行数。 以下代码行:
switch (indexPath.row)
{
case 0 : cell.textLabel.text = @"First Cell"; break;
case 1 : cell.textLabel.text = @"Second Cell"; break;
case 2 : cell.textLabel.text = @"Third Cell"; break;
case 3 : cell.textLabel.text = @"Fourth Cell"; break;
case 4 : cell.textLabel.text = @"Fifth Cell"; break;
case 5 : cell.textLabel.text = @"Sixth Cell"; break;
case 6 : cell.textLabel.text = @"Seventh Cell"; break;
case 7 : cell.textLabel.text = @"Eighth Cell"; break;
default : cell.textLabel.text = [NSString stringWithFormat:@"Cell %i",indexPath.row + 1];
}
用其他代码行代替来调用真实对象属性。
我已经在y项目中包含了所有核心数据堆栈以及NSFetchedResultsController。 核心数据实体有两个属性:tdText,tdDate。 固定部分与tdDate属性相关。
答案 0 :(得分:1)
在这个代码示例中(除了MartinR的建议之外),您正在使用-tableView: numberOfRowsInSection:
方法获取数据。这是令人难以置信的费用,绝对是错误的地方。在您的应用程序生命周期中,该方法会被调用数百次甚至数千次,您应该从不在那里执行提取。
其次,您在-performFetch:
上致电NSFetchedResultsController
。这通常在-viewDidLoad
进行,理想情况下称为一次。从那里你可以再次询问NSFetchedResultsController about its current state; you don't call
- performFetch:`。
其余的。在继续前进之前,您需要退后一步,填补您对Objective-C和核心数据的知识空白。一些评价最高的人在这里得到了很好的答案,而你却没有完全使用它们。如果你沿着这条道路走下去,人们就会停止帮助你。
在提出已经回答的其他问题之前,请完全接受您的建议。
答案 1 :(得分:0)
首先将您的硬编码内容放入更好的结构中,这样您就可以轻松地从Core Data中填充一些数据。
将以下内容添加到viewController的.h文件
NSArray *sectionsArray;
NSMutableDictionary *sectionMenus;
BOOL _searched;
BOOL _loading;
在.m文件中添加以下内容
#define REMINDER_OVERDUE @"Overdue"
#define REMINDER_TODAY @"Today"
#define REMINDER_TOMORROW @"Tomorrow"
#define REMINDER_UPCOMING @"Upcoming"
#define REMINDER_SOMEDAY @"Someday"
#define REMINDER_COMPLETE @"Complete"
#define SEARCHING @"Searching..."
- (void)viewDidLoad
{
[super viewDidLoad];
// This dictionary will be used to store separate Arrays of records for each section using the section title as the key
sectionMenus = [[NSMutableDictionary alloc] init];
// These are the hard coded sections
sectionsArray = [[NSArray alloc] initWithObjects: REMINDER_OVERDUE, REMINDER_TODAY, REMINDER_TOMORROW, REMINDER_UPCOMING, REMINDER_SOMEDAY, REMINDER_COMPLETE, nil];
// We start by populating the sections with a single record containing the string "Searching..." so the user
// will see that the section is busy searching for data to display
[sectionMenus setObject:[[NSArray alloc] initWithObjects: SEARCHING, nil] forKey: REMINDER_OVERDUE];
[sectionMenus setObject:[[NSArray alloc] initWithObjects: SEARCHING, nil] forKey: REMINDER_TODAY];
[sectionMenus setObject:[[NSArray alloc] initWithObjects: SEARCHING, nil] forKey: REMINDER_TOMORROW];
[sectionMenus setObject:[[NSArray alloc] initWithObjects: SEARCHING, nil] forKey: REMINDER_UPCOMING];
[sectionMenus setObject:[[NSArray alloc] initWithObjects: SEARCHING, nil] forKey: REMINDER_SOMEDAY];
[sectionMenus setObject:[[NSArray alloc] initWithObjects: SEARCHING, nil] forKey: REMINDER_COMPLETE];
_searched = NO;
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
// Each time the view appears we check to see if a search has been done and if not then perform a search
if (!_searched) {
_searched=YES;
[self getMenus];
}
}
// tableView delegate methods to use the array and dictionary as the data sources
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return [sectionsArray count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [[sectionMenus objectForKey:[sectionsArray objectAtIndex:section]] count];
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return [[sectionsArray objectAtIndex:section] description];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = @"Cell";
static NSString *inactiveTableIdentifier = @"InactiveTableItem";
UITableViewCell *cell;
NSObject *node =[[sectionMenus objectForKey:[sectionsArray objectAtIndex:[indexPath section]]] objectAtIndex:[indexPath row]];
cell = [tableView dequeueReusableCellWithIdentifier:inactiveTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:inactiveTableIdentifier];
}
cell.textLabel.text = [node description];
return cell;
}
// This methods performs the queries to get the data for each section
// and loads each section when its done (ideally should be done in background)
- (void)getMenus
{
_loading = YES;
[self makeOverdueMenus];
UITableView *tableView = (UITableView *)self.view;
[tableView reloadSections:[[NSIndexSet alloc] initWithIndex:0] withRowAnimation:UITableViewRowAnimationAutomatic];
[self makeTodaysMenus];
[tableView reloadSections:[[NSIndexSet alloc] initWithIndex:1] withRowAnimation:UITableViewRowAnimationAutomatic];
[self makeTomorrowsMenus];
[tableView reloadSections:[[NSIndexSet alloc] initWithIndex:2] withRowAnimation:UITableViewRowAnimationAutomatic];
_loading = NO;
[tableView reloadData];
}
- (void)makeOverdueMenus {
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"dueDate < %@",[NSDate date]];
[self makeMenu: REMINDER_OVERDUE predicate:predicate];
}
- (void)makeTodaysMenus {
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"dueDate >= %@ and dueDate < %@",[NSDate date], [NSDate date]];
[self makeMenu: REMINDER_TODAY predicate:predicate];
}
- (void) makeTomorrowsMenus {
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"dueDate >= %@ and dueDate <= %@",[NSDate date], [NSDate date]];
[self makeMenu: REMINDER_TOMORROW predicate:predicate];
}
// Helper function to get the section items and add them to the dictionary
- (void)makeMenu:(NSString*)section predicate:(NSPredicate*)predicate {
NSMutableArray *reminders = [[NSMutableArray alloc] init];
[reminders addObjectsFromArray:[self getDataSimple];
[sectionMenus setObject:reminders forKey:section];
}
// Simple method to fetch data from Core Data store
- (NSArray*)getDataSimple {
// replace this line with a core data query
NSArray * results = [[NSArray alloc] initWithObjects:@"First Cell", @"Second Cell", @"Third Cell", nil];
return results;
}