views:

509

answers:

1

In a lot of iPhone apps, I see a UITableViewController being used as a checkbox list. (See, for an example of what I mean, Auto-Lock under Settings)

While trying to implement this myself, I had to jump through a lot of hoops in order to have an item selected programmatically by default (ie., the current value for what the list represents). The best I've been able to come up with is by overriding the viewDidAppear method in my view controller class:

- (void)viewDidAppear:(BOOL)animated {
    NSInteger row = 0;

    // loop through my list of items to determine the row matching the current setting
    for (NSString *item in statusItems) {
     if ([item isEqualToString:currentStatus]) {
      break;
     }
     ++row;
    }

    // fetch the array of visible cells, get cell matching my row and set the
    // accessory type
    NSArray *arr = [self.tableView visibleCells];
    NSIndexPath *ip = [self.tableView indexPathForCell:[arr objectAtIndex:row]];
    UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:ip];
    cell.accessoryType = UITableViewCellAccessoryCheckmark;

    self.lastIndexPath = ip;

    [super viewDidAppear:animated];
}

Is this the best/only/easiest way to get a reference to a particular cell and indexPath if I want to mark a row by default?

+1  A: 

In order to display the status items, you have to implement tableView:cellForRowAtIndexPath: anyway, don't you? So, why not just set the accessory type of the cell before returning the cell, like this:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    // dequeue or create cell as usual

    // get the status item (assuming you have a statusItems array, which appears in your sample code)
    NSString* statusItem = [statusItems objectAtIndex:indexPath.row];

    cell.text = statusItem;

    // set the appropriate accessory type
    if([statusItem isEqualToString:currentStatus]) {
        cell.accessoryType = UITableViewCellAccessoryCheckmark;
    }
    else {
        cell.accessoryType = UITableViewCellAccessoryNone;
    }

    return cell;
}

Your code is extremely fragile, especially because you use [self.tableView visibleCells]. What if there are more status items than rows fitting on the screen (as the name suggests, visibleCells only returns the currently visible cells of the table view)?

Daniel Rinser
See, I figured I was being dumb with that code. Slow brain today :P
Dana