Last active
December 18, 2015 05:39
-
-
Save chriseidhof/5734512 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I didn't event know that is possible:
@implementation THTableController {
UITableView* tableView;
NSFetchedResultsController* fetchedResultsController;
CBEModel* model;
}
Is putting ivars directly behind @implementation documented somewhere?