Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Grouping core data tableView rows in manually created sections

I have a Company entity with about 20 fields and I'm wanting to use a grouped tableView with manually created section headers (ie: General, Financial, Misc.), but I am unsure of how to make Core Data understand how to treat these section headers and make them relate only to the data I want to show in these groups.

For example, name, logo, etc would go under General, budgets, cash would go under financial, etc.

Basically, I want to control what data from Core data gets put into each category and display it.

In the Core books sample there is this code:

/*
 The data source methods are handled primarily by the fetch results controller
 */

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return [[fetchedResultsController sections] count];
}


// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {

    id <NSFetchedResultsSectionInfo> sectionInfo = [[fetchedResultsController sections] objectAtIndex:section];
    return [sectionInfo numberOfObjects];
}

But how do I make it understand that the sections aren't in Core data, but created manually?

like image 434
zardon Avatar asked Nov 15 '22 03:11

zardon


1 Answers

I've got an answer to my problem now, I do not know if its the correct approach, but it is working and would welcome comments.

Just to clarify what the problem was, and what I was trying to do.

I have a core data entity company with about 10 or so fields inside them, however rather than listing them all in one go, I wanted to group the outputted fields.

For example, I have about 6 fields relating to cash such as "cash", "marketingBudget", "seoBudget", etc and I wanted to group this data on the tableView, but the problem was I didn't know how to set up a relationship so that table.field.x belonged to group.x, and so on.

The answer I came to was to use a PLIST/dictionary that pretty much mirrors the structure of the core data entity; and assign the structure to the groups I want to display.

My dictionary looks like this;

(root)

->CompanyTpl (array)

--> Item 0 (Dictionary)

---> Section (String) = "General"

---> Children (Array ) ------> Item 0 (Dictionary)

----------> Key = "name"

----------> Value = "Company Name" ...

Where the Key would be a reference for Core Data to use and display its contents, if required.

Where the Value would be would to display at the cellForRowAtIndexPath.

So, in my code I basically went through the section (by which I mean tableView section) and then find the correlating children info from the PLIST; and get the Key/Value and use this as and when required.

Here is a cut down version of the code.

- (void)viewDidLoad {
    NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"CompanyTpl" ofType:@"plist"];
    self.companyDictionary = [[NSDictionary dictionaryWithContentsOfFile:plistPath] retain];

    // self.tableDataSource is a NSMutableArray
    self.tableDataSource = [self.companyDictionary objectForKey:@"CompanyTpl"];

    // Debugging info
    NSLog(@"Section = 0");

    NSLog(@"%@", [self.tableDataSource objectAtIndex:0]);

    NSLog(@"Section Name = %@", [[self.tableDataSource objectAtIndex:0] objectForKey:@"Section"]);


    NSArray *sectionChildren = [[self.tableDataSource objectAtIndex:0] objectForKey:@"Data"];

    NSLog(@"Section Children = %@", sectionChildren);
    NSLog(@"Count of Section Children = %d", [sectionChildren count]);


}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return ([self.tableDataSource count]);
}

// Section header
-(NSString*)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
    NSString *title = nil;

    title = [[self.tableDataSource objectAtIndex:section] objectForKey:@"Section"];

    return title;
}


// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{
NSInteger rows = 0;

    NSArray *sectionChildren = [[self.tableDataSource objectAtIndex:section] objectForKey:@"Data"];

    NSLog(@"Section Children = %@", sectionChildren);
    NSLog(@"Count of Section Children = %d", [sectionChildren count]);

    rows = [sectionChildren count];


    return rows;
}

// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView 
         cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{

    NSArray *sectionChildren            = [[self.tableDataSource objectAtIndex:indexPath.section] objectForKey:@"Data"];
    NSDictionary *sectionChildrenData   = [sectionChildren objectAtIndex:indexPath.row];

    //NSLog(@"Section Children data = %@", sectionChildrenData);

    NSString *scKey     = [sectionChildrenData objectForKey:@"Key"];
    NSString *scValue   = [sectionChildrenData objectForKey:@"Value"];

    NSLog(@"scKey = %@", scKey);

    // Grab the data from Core Data using the scKey



    static NSString *CellIdentifier = @"defaultCell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) 
    {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];


        //cell.textLabel.text = @"test";

        cell.textLabel.text = scValue;
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

    }
    return cell;
}

The idea would be that I can use the KEY when referencing Core Data to grab its contents and display it on the tableView controller at cellForRowAtIndexPath cell.textLabel.text value.

One could go a little further in depth and have more info in the PLIST such as what the subtitle should be, etc.

Anyway, would welcome comments and thoughts.

Thanks.

like image 94
zardon Avatar answered May 16 '23 08:05

zardon