Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deriving UITableView sections from NSFetchedResultsController using "to many" relationship

My Core Data model looks like this:

article <--->> category

Is it even remotely possible to use NSFetchedResultsController to produce a UITableView that looks something like this?

Category 1
  - Article A
  - Article B
  - Article C
Category 2
  - Article A
  - Article D
  - Article E
  - Article F
Category 3
  - Article B
  - Article C

Specifically, I'm interested in the (edge?) case where each UITableView section has a unique title (eg, "Category 1", "Category 2"), but the same object can exist in multiple sections (eg, Article A exists in both Category 1 and Category 2).

I have scoured Apple's Core Data docs and have spent two days perusing questions here, but alas, no luck even finding out whether this is possible, let alone how to implement it. Thanks for any help or pointers to a previously answered question. I certainly couldn't find it.

like image 477
Dave Avatar asked Dec 01 '11 01:12

Dave


1 Answers

Yes, it's easy, though there are a million ways to do it.

Your view controller should be the "data source" of the UITableView, and returns information about the number of rows there are and then the contents of each individual row.

There is a concept of a "section" in a tableview, you might choose to have one for each category.

For example, you could create an NSFetchedResultsController to find the categories you want to display, and use that to populate the table view sections, and then each category would have an articles many-to-many relationship, to populate the rows in each section.

Something like this should get you started (assuming your category and article entities both contain a title property):

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
   // return the number of categories
    [[self.categoryResultsController fetchedObjects] count];
}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
  // return the title of an individual category
    [[self.categoryResultsController.fetchedObjects objectAtIndex:section] valueForKey:@"title"];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
  // return the number of articles in a category
  MyCategory *category = [self.categoryResultsController.fetchedObjects objectAtIndex:section];

  return category.articles.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
  // fetch a cached cell object (since every row is the same, we re-use the same object over and over)
    static NSString *identifier = @"ArticleCellIdentifier";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier] autorelease];
    }

    // find the category and article, and set the text of the cell
    MyCategory *category = [self.categoryResultsController.fetchedObjects objectAtIndex:indexPath.section];

    cell.textLabel.text = [[category.articles objectAtIndex:indexPath.row] valueForKey:@"title"];

    return cell;
}

You can read the documentation on these methods to figure out how to customise it further.

like image 127
Abhi Beckert Avatar answered Oct 19 '22 01:10

Abhi Beckert