Friday, June 21, 2013

NSMutableIndexSet removeAllIndexes example in Objective C (iOS).


NSMutableIndexSet removeAllIndexes

Removes the receiver’s indexes.

- (void)removeAllIndexes

NSMutableIndexSet removeAllIndexes example.
#import "NumberCreator.h"

@implementation NumberCreator
@synthesize levels, numbers;

- (id)init
{
    if ( !(self = [super init] ) )
        return nil;

    numbers = [NSMutableIndexSet new];
    return self;
}

- (void)create
{
    [numbers removeAllIndexes];
    [numbers addIndex:1];

    NSMutableIndexSet *nextLevel = [NSMutableIndexSet indexSet];
    NSMutableIndexSet *currentLevel = [NSMutableIndexSet indexSetWithIndex:1];

    for (int i = 0; i < levels; i++ )
    {
        [currentLevel enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {

            if ( ! [numbers containsIndex:idx * 2] )
                [nextLevel addIndex:idx * 2];

            if ( idx % 6 == 4 && ! [numbers containsIndex:(idx - 1) / 3] )
                [nextLevel addIndex:(idx - 1) / 3];
        }];

        [numbers addIndexes:nextLevel];
        [currentLevel removeAllIndexes];
        [currentLevel addIndexes:nextLevel];
        [nextLevel removeAllIndexes];
    }

    [numbers enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
        NSLog(@"%i", idx);
    }];
}

@end

Example of [NSMutableIndexSet removeAllIndexes].
//Not tested
//Assume that selectedIndexes is a NSMutableIndexSet
if ([selectedIndexes containsIndex:indexPath.row]) {
    if (self.options.count) {//This could probably be optimised depend on your goal
        [selectedIndexes addIndexesInRange:NSMakeRange(0,self.options.count-1)];
    } else {
        [selectedIndexes removeAllIndexes];
    }

NSMutableIndexSet removeAllIndexes example.
- (void)createFilteredTableGroups{

    //Checking for the usual suspects. all which may through an exception
    if(model==nil)
        return;
    if(tableGroups==nil)
        return;
    if([tableGroups count]==0)
        return;

    //lets make a new array to work with
    NSMutableArray *newTableGroups = [[allTableGroups mutableCopy] autorelease];

    //telling the table what we are about to do
    [self.tableView beginUpdates];

    //array to track cells for deletion animation
    NSMutableArray *indexesToRemove = [NSMutableArray array];

    //loop through each section
    for(NSMutableArray *eachSection in tableGroups){

        //keeping track of the indexes to delete for each section
        NSMutableIndexSet *indexesForSection = [NSMutableIndexSet indexSet];
        [indexesForSection removeAllIndexes];

        //increment though cell indexes
        int rowIndex = 0;

        //loop through each cellController in the section
        for(ScheduleCellController *eachCellController in eachSection){

            //Ah ha! A little magic. the cell controller must know if it should be displayed.
            //This you must calculate in your business logic
            if(![eachCellController shouldDisplay]){

                //add non-displayed cell indexes
                [indexesForSection addIndex:rowIndex];

            }
            rowIndex++;  
        }
        //adding each array of section indexes, EVEN if it is empty (no indexes to delete)
        [indexesToRemove addObject:indexesForSection];

    }

    //Now we remove cell controllers in newTableGroups and cells from the table
    //Also, each subarray of newTableGroups is mutable as well
    if([indexesToRemove count]>0){

        int sectionIndex = 0;
        for(NSMutableIndexSet *eachSectionIndexes in indexesToRemove){

            //Now you know why we stuck the indexes into individual arrays, easy array method
            [[newTableGroups objectAtIndex:sectionIndex] removeObjectsAtIndexes:eachSectionIndexes];

            //tracking which cell indexPaths to remove for each section
            NSMutableArray *indexPathsToRemove = [NSMutableArray array];
            int numberOfIndexes = [eachSectionIndexes count];

            //create array of indexPaths to remove
            NSUInteger index = [eachSectionIndexes firstIndex];
            for(int i = 0; i< numberOfIndexes; i++){

                NSIndexPath *indexPath = [NSIndexPath indexPathForRow:index inSection:sectionIndex];
                [indexPathsToRemove addObject:indexPath];
                index = [eachSectionIndexes indexGreaterThanIndex:index];
            }

            //delete the rows for this section
            [self.tableView deleteRowsAtIndexPaths:indexPathsToRemove withRowAnimation:UITableViewRowAnimationTop];

            //next section please
            sectionIndex++;
        }

    }

    //now we figure out if we need to remove any sections
    NSMutableIndexSet *sectionsToRemove = [NSMutableIndexSet indexSet];
    [sectionsToRemove removeAllIndexes];

    int sectionsIndex = 0;
    for(NSArray *eachSection in newTableGroups){

        //checking for empty sections
        if([eachSection count]==0)
            [sectionsToRemove addIndex:sectionsIndex];

        sectionsIndex++;
    }

    //updating the table groups
    [newTableGroups removeObjectsAtIndexes:sectionsToRemove];

    //removing the empty sections
    [self.tableView deleteSections:sectionsToRemove withRowAnimation:UITableViewRowAnimationTop];

    //updating filteredTableGroups to the newTableGroups we just created
    self.filteredTableGroups = newTableGroups;

    //pointing tableGroups at the filteredGroups
    tableGroups = filteredTableGroups;

    //invokes the animation
    [self.tableView endUpdates];

}

End of NSMutableIndexSet removeAllIndexes example article.