Wednesday, June 19, 2013

NSIndexPath indexPathByAddingIndex example in Objective C (iOS).


NSIndexPath indexPathByAddingIndex

Provides an index path containing the indexes in the receiving index path and another index.

- (NSIndexPath *)indexPathByAddingIndex:(NSUInteger)index

Parameters
index
Index to append to the index path’s indexes.

Return Value of [NSIndexPath indexPathByAddingIndex]
New NSIndexPath object containing the receiving index path’s indexes and index.

NSIndexPath indexPathByAddingIndex example.
NSUInteger newIndexes[] = {0,1};
NSUInteger len = sizeof(newIndexes)/sizeof(NSUInteger); //sorry!
NSIndexPath *baseIndexPath = [NSIndexPath indexPathWithIndexes:newIndexes
                                                        length:len];
NSUInteger i;
for (i=0; i<10; i++) {
    NSIndexPath *newIndexPath = [baseIndexPath indexPathByAddingIndex:i];
    NSLog(@"newIndexPath = %@", newIndexPath);
}
Or you may want to increment an existing indexPath (the first line instantiates an indexPath with the newIndexes array from the example above):

NSIndexPath *someIndexPath = [NSIndexPath indexPathWithIndexes:newIndexes
                                                        length:len];
    NSUInteger newIndexes2[[someIndexPath length]];
    [someIndexPath getIndexes:newIndexes2];

    NSUInteger len2 = sizeof(newIndexes2)/sizeof(NSUInteger);
    NSIndexPath *baseIndexPath2 = [NSIndexPath indexPathWithIndexes:newIndexes2
                                                             length:len2];
    NSUInteger ii;
    NSInteger start = [someIndexPath indexAtPosition:[someIndexPath length] -1];
    for (ii=start; ii<10; ii++) {
        NSIndexPath *newIndexPath2 = [baseIndexPath2 indexPathByAddingIndex:ii];
        NSLog(@"newIndexPath2 = %@", newIndexPath2);
    }
Note that the first example will create children of the original path 0.1, while the second one creates siblings. Mix 'n match as you like.

Example of [NSIndexPath indexPathByAddingIndex].
You can try this - perhaps equally clunky, but at least a bit shorter:

NSInteger newLast = [indexPath indexAtPosition:indexPath.length-1]+1;
indexPath = [[indexPath indexPathByRemovingLastIndex] indexPathByAddingIndex:newLast];

NSIndexPath indexPathByAddingIndex example.
- (id)objectInArray:(id)array atIndexPath:(NSIndexPath *)path {

    // the end of recursion
    if (![array isKindOfClass:[NSArray self]] || !path.length) return array;

    NSUInteger nextIndex = [path indexAtPosition:0];

    // this will (purposely) raise an exception if the nextIndex is out of bounds
    id nextArray = [array objectAtIndex:nextIndex];

    NSUInteger indexes[27]; // maximum number of dimensions per string theory :)
    [path getIndexes:indexes];
    NSIndexPath *nextPath = [NSIndexPath indexPathWithIndexes:indexes+1 length:path.length-1];

    return [self objectInArray:nextArray atIndexPath:nextPath];
}
Call it like this...

NSArray *array = [NSArray arrayWithObjects:@1, [NSArray arrayWithObjects:@"hi", @"there", nil], @3, nil];

NSIndexPath *indexPath = [NSIndexPath indexPathWithIndex:1];
indexPath = [indexPath indexPathByAddingIndex:1];

NSLog(@"%@", [self objectInArray:array atIndexPath:indexPath]);

End of NSIndexPath indexPathByAddingIndex example article.