Jonathan Thurft
Jonathan Thurft

Reputation: 4173

How to create a dynamic size array

What I am trying to achieve:

I have a UITableView and I want to check whether the table was selected or not and keep in an array easy to access the YES or NO values that corresponds to that row so that afterwards i can manipulate the data.

my code as follows

- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSUInteger row = [indexPath row];

    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    NSString *cellLabelText = cell.textLabel.text;

    if (cell.accessoryType == UITableViewCellAccessoryCheckmark) {
        cell.accessoryType = UITableViewCellAccessoryNone;
        selected[row] = NO;
    }
    else {
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
        selected[row] = YES;
    }  
}

As it stands out I can create a BOOL selected[some value] but my problem is that the max index needed for me is unknown as my table size changes constantly. thus setting the max index limits me.

I am new to objective C and I come from a PHP background thus I dont know whether it is possible to create an array that does what i want to do in objective-c.

Otherwise what would be my options within objective-c to have an easy way to easy write/read selected[row] = YES/NO.

I need a way to write YES/NO and link it to the indexpath.row

Upvotes: 0

Views: 1230

Answers (4)

vikingosegundo
vikingosegundo

Reputation: 52227

Instead of an array you can use a index set.

@property (nonatomic,strong) NSMutableIndexSet *pickedIndexPaths;

- (void)viewDidLoad
{
    _pickedSIndexPaths = [[NSMutableIndexSet alloc] init];
    [super viewDidLoad];
}


-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //…

    if(indexPath.section == 0) {
        cell.textLabel.text = self.sports[indexPath.row][@"sport"][@"name"];
        if ([_pickedIndexPaths containsIndex:indexPath.row]) {
            [cell setAccessoryType:UITableViewCellAccessoryCheckmark];
        } else {
            [cell setAccessoryType:UITableViewCellAccessoryNone];
        }
    }
    return cell;
}


-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    if ([_pickedIndexPaths containsIndex:indexPath.row]) {
        [_pickedIndexPaths removeIndex:indexPath.row];
    } else {
        [_pickedIndexPaths addIndex:indexPath.row];
    }
    [tableView reloadData];
    }
}

Upvotes: 1

justin
justin

Reputation: 104698

When what you need is a variable length array of boolean values, you can use CFBitVectorRef. This will consume much less memory than using a Cocoa collection designed for objc object values (provided of course that array has many elements) because it consumes 1 bit for each value, rather than a full pointer which points to an individual dynamically allocated reference counted object.

Upvotes: 0

rmaddy
rmaddy

Reputation: 318804

Use an NSMutableSet and store the NSIndexPath of the selected rows. If you select a row you add the path to the set. If you unselect a row, remove the path from the set.

To see if a row is selected, see if the indexPath is in the set or not.

BTW - this only works if the rows are fixed. If the user can add, remove, or reorder rows then this approach will not work. In such a case you need to store data keys, not index paths.

Create an ivar of type NSMutableSet. Let's call it selectedRows:

selectedRows = [[NSMutableSet alloc] init];

Then in didSelectRow you do:

- (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    BOOL selected = [selectedRows containsObject:indexPath];

    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    NSString *cellLabelText = cell.textLabel.text;

    if (selected) {
        cell.accessoryType = UITableViewCellAccessoryNone;
        [selectedRows removeObject:indexPath];
    } else {
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
        [selectedRows addObject:indexPath];
    }  
}

In your cellForRow... method you do something similar:

BOOL selected = [selectedRows containsObject:indexPath];
cell.accessoryType = selected ? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;

Upvotes: 5

Mundi
Mundi

Reputation: 80265

Just use

NSMutableArray *dynamicArray = [NSMutableArray array]; 

You can add and delete objects from this at will. Just be sure to use the NSNumber wrapper to add primitives:

[dynamicArray addObject:[NSNumber numberWithInt:indexNumber]];
// or
[dynamicArray addObject:@(indexNumber)];

Upvotes: 1

Related Questions