UITableView cargado desde MutableArray se convierte en una lista de casillas de verificación

I have an tableview which is loaded from a mutablearray as listed below. However I need to asign each item in the array an ID and have a tickbox next to the item. Basically it's preferences for our search, it lets users prioritise by whichever tickboxes are ticked. So I'll want to save which items are ticked to a plist or similar.

Heres how the array is loaded:

arryTableIconsText =     [[NSMutableArray alloc] init]; 

[arryTableIconsText addObject:@"Facilities for partially sighted or blind people"];
[arryTableIconsText addObject:@"An 'assistance dogs welcome' policy"];
[arryTableIconsText addObject:@"Disabled access facilities for wheelchair users (with assistance)"];
*more items added here*

arryTableIcons = [[NSMutableArray alloc] init];

[arryTableIcons addObject:@"visuallyImpaired_off.png"];
[arryTableIcons addObject:@"guidedogs_off.png"];
[arryTableIcons addObject:@"wheelchairassist_off.png"];
    *more items added here*

And then loaded in to a table like so:

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

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];

    cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
    cell.textLabel.numberOfLines = 0;
    cell.textLabel.font = [UIFont fontWithName:@"Helvetica" size:17.0];

    cell.textLabel.text = [arryTableIconsText objectAtIndex:indexPath.row];
    cell.imageView.image = [UIImage imageNamed:[arryTableIcons objectAtIndex:indexPath.row]];   

    return cell;

El resultado es el siguiente:


But I don't know where to go from here to convert it in to a checkbox to the right of each cell with the ID saved?

Any tips really will be appreciated, Tom

preguntado el 08 de noviembre de 11 a las 14:11

1 Respuestas

Usa una NSMutableIndexSet instance variable and populate it with the index of the cells being checked.

Entonces en el cellForRowAtIndexPath method, set the accessory type of the cell to UITableViewCellAccessoryTypeCheckmark or UITableViewCellAccessoryTypeNone depending on whereas the indexPath.row is in the NSMutableIndexSet or not.

Finally, when the cell is tapped, add the indexPath.row to the indexset if not alread, or remove it if it already was present, to toggle the status of the corresponding cell, then call reloadData en el tableView.

I see in your code too that you are not familiar with the reuse mechanism of UITableViewCells. You should read the "Table View Programming Guide" in Apple's documentation and learn how to implement cellForRowAtIndexPath in a more efficient and reactive way (in term of reactivity and memory footprint)


// Let selectedCellIndexes be an instance variable in your .h of type NSMutableIndexSet*
// Initialize it (probably at the same place you initialise your texts & icons, once for all, probably in your init method
selectedCellIndexes = [[NSMutableIndexSet alloc] init];

Then to fill the cells:

-(UITableViewCell*)tableView:(UITableView*)tv cellForRowAtIndexPath:(NSIndexPath*)indexPath {
  // Try to recycle and already allocated cell (but not used anymore so we can reuse it)
  UITableViewCell* cell = [tv dequeueCellWithReuseIdentifier:...];
  if (cell == nil) {
    // If we didn't manage to get a reusable (existing) cell to recycle it
    // then allocate a new one and configure its general properties common to all cells
    cell = [[[UITableViewCell alloc] initWithStyle:... reuseIdentifier:...] autorelease];

    // ... configure stuff that are common to all your cells : lineBreakMode, numberOfLines, font... once for all
    cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
    cell.textLabel.numberOfLines = 0;
    cell.textLabel.font = [UIFont fontWithName:@"Helvetica" size:17.0];

  // Then here change the stuff that are different between each cell
  // (this code will be executed if the cell has just been allocated as well as if the cell is an old cell being recycled)
  cell.textLabel.text = [arryTableIconsText objectAtIndex:indexPath.row];
  cell.imageView.image = [UIImage imageNamed:[arryTableIcons objectAtIndex:indexPath.row]];
  cell.accessoryType = [selectedCellIndexes containsIndex:indexPath.row] ? UITableViewCellAccessoryTypeCheckmark : UITableViewCellAccessoryTypeNone;

  return cell;

And finally, to toggle the checkmarks:

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

respondido 08 nov., 11:19

Thanks for that, i've not used NSMutableIndexSet before, do I use it in conjunction with the NSMutableArray? - MissCoder87

Thanks a lot for that, just working through it now. On the last line of your cell you have cell.accessoryType = [selectedCellIndexes containsIndex:indexPath.row] ? UITableViewCellAccessoryTypeCheckmark : UITableViewCellAccessoryTypeNone; - is that correct? The question mark looks out of place - Tom - MissCoder87

That's the ternary operator. If you don't know this C operator, you can just replace it with an "if" statement: x = a ? b : c is the exact equivalent to if (a) { x = b; } else { x = c; }. Véase la Wikipedia for more info on this operator. - AliSoftware

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.