diff --git a/Code/UI/RKAbstractTableController.h b/Code/UI/RKAbstractTableController.h index 4687b109..06885502 100755 --- a/Code/UI/RKAbstractTableController.h +++ b/Code/UI/RKAbstractTableController.h @@ -110,6 +110,13 @@ extern NSString* const RKTableControllerDidBecomeOffline; - (id)objectForRowAtIndexPath:(NSIndexPath *)indexPath; - (RKTableViewCellMapping*)cellMappingForObjectAtIndexPath:(NSIndexPath *)indexPath; +/** + Return the index path of the object within the table + */ +- (NSIndexPath *)indexPathForObject:(id)object; +- (id)objectAtIndexPath:(NSIndexPath *)indexPath; +- (UITableViewCell *)cellForObject:(id)object; + ///////////////////////////////////////////////////////////////////////// /// @name Header and Footer Rows ///////////////////////////////////////////////////////////////////////// diff --git a/Code/UI/RKAbstractTableController.m b/Code/UI/RKAbstractTableController.m index 94b320a1..72059381 100755 --- a/Code/UI/RKAbstractTableController.m +++ b/Code/UI/RKAbstractTableController.m @@ -417,6 +417,34 @@ static NSString* lastUpdatedDateDictionaryKey = @"lastUpdatedDateDictionaryKey"; return [self.cellMappings cellMappingForObject:object]; } +- (UITableViewCell *)cellForObject:(id)object { + NSIndexPath *indexPath = [self indexPathForObject:object]; + return indexPath ? [self cellForObjectAtIndexPath:indexPath] : nil; +} + +// TODO: unit test... +// TODO: This needs to be updated to take into account header & footer rows... +- (NSIndexPath *)indexPathForObject:(id)object { + NSUInteger sectionIndex = 0; + for (RKTableSection *section in self.sections) { + NSUInteger rowIndex = 0; + for (id rowObject in section.objects) { + if ([rowObject isEqual:object]) { + return [NSIndexPath indexPathForRow:rowIndex inSection:sectionIndex]; + } + + rowIndex++; + } + sectionIndex++; + } + + return nil; +} + +- (id)objectAtIndexPath:(NSIndexPath *)indexPath { + return [[self.sections objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]; +} + #pragma mark - Header and Footer Rows - (void)addHeaderRowForItem:(RKTableItem*)tableItem { diff --git a/Code/UI/RKFetchedResultsTableController.h b/Code/UI/RKFetchedResultsTableController.h index 49f33bc5..e66dcdce 100755 --- a/Code/UI/RKFetchedResultsTableController.h +++ b/Code/UI/RKFetchedResultsTableController.h @@ -33,7 +33,7 @@ typedef UIView*(^RKFetchedResultsTableViewViewForHeaderInSectionBlock)(NSUIntege @property (nonatomic, readonly) NSFetchedResultsController* fetchedResultsController; @property (nonatomic, copy) NSString* resourcePath; -@property (nonatomic, readonly) NSFetchRequest* fetchRequest; +@property (nonatomic, retain) NSFetchRequest* fetchRequest; @property (nonatomic, assign) CGFloat heightForHeaderInSection; @property (nonatomic, copy) RKFetchedResultsTableViewViewForHeaderInSectionBlock onViewForHeaderInSection; @property (nonatomic, retain) NSPredicate* predicate; diff --git a/Code/UI/RKFetchedResultsTableController.m b/Code/UI/RKFetchedResultsTableController.m index 669fd1e9..1ba955b7 100755 --- a/Code/UI/RKFetchedResultsTableController.m +++ b/Code/UI/RKFetchedResultsTableController.m @@ -46,6 +46,7 @@ @synthesize showsSectionIndexTitles = _showsSectionIndexTitles; @synthesize sortSelector = _sortSelector; @synthesize sortComparator = _sortComparator; +@synthesize fetchRequest = _fetchRequest; - (void)dealloc { _fetchedResultsController.delegate = nil; @@ -63,6 +64,8 @@ _cacheName = nil; [_arraySortedFetchedObjects release]; _arraySortedFetchedObjects = nil; + [_fetchRequest release]; + _fetchRequest = nil; Block_release(_onViewForHeaderInSection); Block_release(_sortComparator); [super dealloc]; @@ -185,22 +188,28 @@ #pragma mark - Public -- (NSFetchRequest*)fetchRequest { - return _fetchedResultsController.fetchRequest; +- (NSFetchRequest *)fetchRequest { + return _fetchRequest ? _fetchRequest : _fetchedResultsController.fetchRequest; } - (void)loadTable { - RKManagedObjectStore* store = [RKObjectManager sharedManager].objectStore; - NSAssert(store.managedObjectCache != nil, @"Attempted to load RKFetchedResultsTableController with nil RKManageObjectCache"); + NSFetchRequest *fetchRequest = nil; + if (_resourcePath) { + RKManagedObjectStore* store = [RKObjectManager sharedManager].objectStore; + NSAssert(store.managedObjectCache != nil, @"Attempted to load RKFetchedResultsTableController with nil RKManageObjectCache"); - NSFetchRequest* cacheFetchRequest = [store.managedObjectCache fetchRequestForResourcePath:_resourcePath]; - NSAssert(cacheFetchRequest != nil, @"Attempted to load RKFetchedResultsTableController with nil fetchRequest for resourcePath %@", _resourcePath); + fetchRequest = [store.managedObjectCache fetchRequestForResourcePath:_resourcePath]; + } else { + fetchRequest = _fetchRequest; + } + NSAssert(fetchRequest != nil, @"Attempted to load RKFetchedResultsTableController with nil fetchRequest for resourcePath %@, fetchRequest %@", + _resourcePath, _fetchRequest); if (_predicate) { - [cacheFetchRequest setPredicate:_predicate]; + [fetchRequest setPredicate:_predicate]; } if (_sortDescriptors) { - [cacheFetchRequest setSortDescriptors:_sortDescriptors]; + [fetchRequest setSortDescriptors:_sortDescriptors]; } [_fetchedResultsController setDelegate:nil]; @@ -208,7 +217,7 @@ _fetchedResultsController = nil; _fetchedResultsController = - [[NSFetchedResultsController alloc] initWithFetchRequest:cacheFetchRequest + [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[NSManagedObject managedObjectContext] sectionNameKeyPath:_sectionNameKeyPath cacheName:_cacheName]; @@ -302,8 +311,14 @@ RKTableViewCellMapping* cellMapping = [self.cellMappings cellMappingForObject:mappableObject]; NSAssert(cellMapping, @"Cannot build a tableView cell for object %@: No cell mapping defined for objects of type '%@'", mappableObject, NSStringFromClass([mappableObject class])); - UITableViewCell* cell = [cellMapping mappableObjectForData:self.tableView]; - NSAssert(cell, @"Cell mapping failed to dequeue or allocatate a tableViewCell for object: %@", mappableObject); + // Return an existing cell or initialize a new one + UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath]; + if (! cell) { + cell = [cellMapping mappableObjectForData:self.tableView]; + } + NSAssert(cell, @"Cell mapping failed to dequeue or allocate a tableViewCell for object: %@", mappableObject); + + // Map the object state into the cell RKObjectMappingOperation* mappingOperation = [[RKObjectMappingOperation alloc] initWithSourceObject:mappableObject destinationObject:cell mapping:cellMapping]; NSError* error = nil; BOOL success = [mappingOperation performMapping:&error]; @@ -321,11 +336,15 @@ - (NSIndexPath *)indexPathForObject:(id)object { if ([object isKindOfClass:[NSManagedObject class]]) { - return [_fetchedResultsController indexPathForObject:object]; + return [self indexPathForFetchedResultsIndexPath:[_fetchedResultsController indexPathForObject:object]]; } return nil; } +- (UITableViewCell *)cellForObject:(id)object { + return [self cellForObjectAtIndexPath:[self indexPathForObject:object]]; +} + #pragma mark - UITableViewDataSource methods - (NSInteger)numberOfSectionsInTableView:(UITableView*)theTableView { diff --git a/Code/UI/RKTableController.h b/Code/UI/RKTableController.h index 0f71d0f1..19512e22 100644 --- a/Code/UI/RKTableController.h +++ b/Code/UI/RKTableController.h @@ -39,20 +39,6 @@ - (void)loadObjects:(NSArray *)objects inSection:(NSUInteger)sectionIndex; - (void)loadEmpty; -/** - Return the index path of the object within the table - */ -// TODO: Move to superclass??? -- (NSIndexPath *)indexPathForObject:(id)object; - -/** - */ -// TODO: Move to superclass??? -- (id)objectAtIndexPath:(NSIndexPath *)indexPath; - -// TODO: Move to superclass??? -- (UITableViewCell *)cellForObject:(id)object; - // Move to superclass??? - (void)reloadRowForObject:(id)object withRowAnimation:(UITableViewRowAnimation)rowAnimation; diff --git a/Code/UI/RKTableController.m b/Code/UI/RKTableController.m index f24c0616..4a86e1e1 100644 --- a/Code/UI/RKTableController.m +++ b/Code/UI/RKTableController.m @@ -325,29 +325,6 @@ [self loadObjects:objects inSection:0]; } -// TODO: unit test... -// TODO: This needs to be updated to take into account header & footer rows... -- (NSIndexPath *)indexPathForObject:(id)object { - NSUInteger sectionIndex = 0; - for (RKFormSection *section in self.sections) { - NSUInteger rowIndex = 0; - for (id rowObject in section.objects) { - if ([rowObject isEqual:object]) { - return [NSIndexPath indexPathForRow:rowIndex inSection:sectionIndex]; - } - - rowIndex++; - } - sectionIndex++; - } - - return nil; -} - -- (id)objectAtIndexPath:(NSIndexPath *)indexPath { - return [[self.sections objectAtIndex:indexPath.section] objectAtIndex:indexPath.row]; -} - - (void)reloadRowForObject:(id)object withRowAnimation:(UITableViewRowAnimation)rowAnimation { // TODO: Find the indexPath of the object... NSIndexPath *indexPath = [self indexPathForObject:object]; @@ -356,12 +333,6 @@ } } -- (UITableViewCell *)cellForObject:(id)object { - NSIndexPath *indexPath = [self indexPathForObject:object]; - return indexPath ? [self cellForObjectAtIndexPath:indexPath] : nil; -} - - - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; if ([keyPath isEqualToString:@"sections"]) {