获取对象并将其分类为多个部分

时间:2014-01-11 16:35:16

标签: ios core-data

在我的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属性相关。

2 个答案:

答案 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;

    }