Skip to content

Instantly share code, notes, and snippets.

@chriseidhof
Last active December 18, 2015 05:39
Show Gist options
  • Save chriseidhof/5734512 to your computer and use it in GitHub Desktop.
Save chriseidhof/5734512 to your computer and use it in GitHub Desktop.
#import <Foundation/Foundation.h>
@class CBEModel;
@protocol THTableControllerDelegate
- (void)configureCell:(id)cell item:(id)item;
@end
typedef void (^ConfigureBlock)(id cell, id item);
@interface THTableController : NSObject <UITableViewDataSource>
@property (nonatomic, weak) id<THTableControllerDelegate> delegate;
@property (nonatomic, copy) ConfigureBlock configureCellBlock;
- (id)initWithTableView:(UITableView*)aTableView fetchedResultsController:(NSFetchedResultsController*)aFetchedResultsController model:(CBEModel*)model;
- (void)changePredicate:(NSPredicate*)predicate;
- (id)selectedItem;
@end
#import "THTableController.h"
@interface THTableController () <NSFetchedResultsControllerDelegate>
@end
@implementation THTableController {
UITableView* tableView;
NSFetchedResultsController* fetchedResultsController;
CBEModel* model;
}
- (id)initWithTableView:(UITableView*)aTableView fetchedResultsController:(NSFetchedResultsController*)aFetchedResultsController model:(CBEModel*)aModel {
self = [super init];
if (self) {
tableView = aTableView;
fetchedResultsController=aFetchedResultsController;
model = aModel;
[self setup];
}
return self;
}
- (void)setup {
tableView.dataSource = self;
fetchedResultsController.delegate = self;
[fetchedResultsController performFetch:NULL];
}
- (void)changePredicate:(NSPredicate*)predicate {
NSAssert(fetchedResultsController.cacheName == NULL, @"Can't change predicate when you have a caching fetched results controller");
NSFetchRequest* fetchRequest = fetchedResultsController.fetchRequest;
fetchRequest.predicate = predicate;
NSInteger numberOfSections = tableView.numberOfSections;
[fetchedResultsController performFetch:NULL];
NSInteger newNumberOfSections = fetchedResultsController.sections.count;
if(numberOfSections == newNumberOfSections) {
NSIndexSet* indexSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, (NSUInteger) numberOfSections)];
[tableView reloadSections:indexSet withRowAnimation:UITableViewRowAnimationRight];
} else {
[tableView reloadData];
}
}
- (id)itemAtIndexPath:(NSIndexPath*)path {
return [fetchedResultsController objectAtIndexPath:[NSIndexPath indexPathForRow:path.row inSection:path.section]];
}
- (id)selectedItem {
return [self itemAtIndexPath:[tableView indexPathForSelectedRow]];
}
- (void)configureCell:(UITableViewCell*)cell atIndexPath:(NSIndexPath*)path {
id item = [self itemAtIndexPath:path];
if(self.delegate) {
[self.delegate configureCell:cell item:item];
} else if(self.configureCellBlock) {
self.configureCellBlock(cell, item);
}
}
#pragma mark UITableViewDataSource
- (NSInteger)numberOfSectionsInTableView:(UITableView*)aTableView {
return fetchedResultsController.sections.count;
}
- (NSInteger)tableView:(UITableView*)aTableView numberOfRowsInSection:(NSInteger)section {
return [fetchedResultsController.sections[(NSUInteger) section] numberOfObjects];
}
- (NSString*)tableView:(UITableView*)aTableView titleForHeaderInSection:(NSInteger)section {
id <NSFetchedResultsSectionInfo> info = [fetchedResultsController sections][(NSUInteger) section];
return info.name;
}
- (UITableViewCell*)tableView:(UITableView*)aTableView cellForRowAtIndexPath:(NSIndexPath*)indexPath {
UITableViewCell* cell = [aTableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
[self configureCell:cell atIndexPath:indexPath];
return cell;
}
#pragma mark NSFetchedResultsControllerDelegate
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
[tableView endUpdates];
}
- (void)controllerWillChangeContent:(NSFetchedResultsController*)controller {
[tableView beginUpdates];
}
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {
switch(type) {
case NSFetchedResultsChangeInsert:
[tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex]
withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex]
withRowAnimation:UITableViewRowAnimationFade];
break;
default:
break;
}
}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath {
switch(type) {
case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
[self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
break;
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
default:
break;
}
}
#pragma mark Editing
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
NSManagedObject* object = [fetchedResultsController objectAtIndexPath:indexPath];
[object.managedObjectContext deleteObject:object];
}
}
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
// The table view should not be re-orderable.
return NO;
}
@end
@iljaiwas
Copy link

iljaiwas commented Jun 8, 2013

I didn't event know that is possible:

@implementation THTableController {
UITableView* tableView;
NSFetchedResultsController* fetchedResultsController;
CBEModel* model;
}

Is putting ivars directly behind @implementation documented somewhere?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment