Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Non-Core Data data in a Core Data-backed UITableView

Take a look at the Music.app (or iPod.app). The root Albums view has an "All Songs" row. The root Songs view has a "Shuffle" row. The root Playlists view has an "Add Playlist..." row. Static data mixed in the same UITableView with (presumably) Core Data data. I'm wondering how Apple achieved this.

I've tried two different approaches, both failed. Like the Music.app, my views also have a UISeachBar in the tableHeaderView. My first attempt kept track of how many "static" rows I had and adjusted the indexPath provided to the various UITableView and NSFetchedResultsController methods that require section and row info. Everything was working great until I implemented the NSFetchedResultsControllerDelegate methods to allow creating, editing and deleting. The insertRowsAtIndexPaths:withRowAnimation: method (and similar) gets tripped up on my adjusted indexPaths. The default indexPaths don't work as is either.

My second attempt was to nest another UITableView in the tableHeaderView of my primary UITableView to use for the static rows (and to house the UISeachBar in it's own tableHeaderView). This approach didn't even make it to the editable stage. The UISearchBar ends up being overlapped by the root UITableView's sectionIndex scrubber and no longer slides up behind the UINavigationBar when scrolling a short list.

So rather than diagnose my specific problems I'm asking for suggestions on how Apple achieves this. Could they be fetching the data once, caching it in an NSArray and constructing a nested NSArray of sections and rows that includes both the static and Core Data rows?

like image 949
Shaun Inman Avatar asked Oct 14 '22 20:10

Shaun Inman


1 Answers

I ran into this same problem recently. I wanted to add a row at the top of the table with some static content (All Songs). I got around the issue by simply inserting my own section for section 0, and then incrementing the core data sections. 0 becomes 1, 1 becomes 2, etc.

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return [_fetchedResultsController sections] + 1;
}

- (NSInteger)tableView:(UITableView *)tv numberOfRowsInSection:(NSInteger)section {
    if( section == 0 ) {
        return 1;
    }
    id <NSFetchedResultsSectionInfo> sectionInfo = [[_fetchedResultsController sections] objectAtIndex:section-1];
    return [sectionInfo numberOfObjects];
}

- (UITableViewCell *)tableView:(UITableView *)tv cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    // All Charts
    if( indexPath.section == 0 && indexPath.row == 0 ) {
        // Set up the custom cell
    }
    // Sets
    else {
        // Set up the core data cells
    }
}

The rest is just a matter of adjusting the indexPath sections when removing rows and the like.

like image 173
Daniel Farrelly Avatar answered Nov 15 '22 14:11

Daniel Farrelly