Very often, when you work with UITableViewController
s driven by
NSFetchedResultsController
s, that you want to get the “previous” or
the “next” elements in the results controller. Visually, this operation
corresponds, from the point of view of the user, to select the cell that
sits immediately above or below from the currently selected one.
Of course, you can’t just ++
on the current NSIndexPath
, because
these objects have both a section
and a row
component, and the math
required to jump from one to the other can be quite cumbersome; instead,
it would be useful to have a reusable set of methods, and avoid the
clutter in our controllers.
I have created a very simple category on the NSFetchedResultsController
class that retrieves the “next” and the “last” NSIndexPath
given any
other NSIndexPath
; this can be dropped and reused in your projects and
is very simple to use.
Interface
#import "CoreData/CoreData.h"
@interface NSFetchedResultsController (AKOLibrary)
– (NSIndexPath *)ako_incrementIndexPath:(NSIndexPath *)oldIndexPath;
– (NSIndexPath *)ako_decrementIndexPath:(NSIndexPath *)oldIndexPath;
@end
Implementation
#import "NSFetchedResultsController+AKOLibrary.h"
@implementation NSFetchedResultsController (AKOLibrary)
– (NSIndexPath *)ako_incrementIndexPath:(NSIndexPath *)oldIndexPath
{
NSIndexPath *nextIndexPath = nil;
id <NSFetchedResultsSectionInfo> sectionInfo = [[self sections] objectAtIndex:oldIndexPath.section];
NSInteger rowCount = [sectionInfo numberOfObjects];
NSInteger nextRow = oldIndexPath.row + 1;
NSInteger currentSection = oldIndexPath.section;
if (nextRow = 0)
{
previousIndexPath = [NSIndexPath indexPathForRow:nextRow inSection:currentSection];
}
else
{
NSInteger nextSection = currentSection – 1;
if (nextSection >= 0)
{
previousIndexPath = [NSIndexPath indexPathForRow:0 inSection:nextSection];
}
}
return previousIndexPath;
}
@end
How to use
To use this class, just do the following:
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:19 inSection:4];
NSIndexPath *next = [controller ako_incrementIndexPath:indexPath];
NSIndexPath *previous = [controller ako_decrementIndexPath:indexPath];
If the NSIndexPath
(19,4) was the last of whole table, next
would be
nil
. The same, if NSIndexPath
was the first (0, 0), then previous
would be nil
. In all other situations, the next
and previous
index
paths will correspond to the cells immediately above or below from the
current table.
Hope this helps!