Search code examples
iphoneuitableviewcore-datauiswitch

UISwitch won't turn on when core data state is changed


I have a table where each row represents an object in core data. Each row contains a UISwitch (modified to contain the indexPath of the row that contains it) that when toggled should toggle the state property of the object in core data.

What's currently happening is the switch goes to on when it is touched, and then goes back to off!?

The one clue I have is that when I comment out

// Establish what position the switch should be in
    if([info.state isEqualToString:@"on"]){
        mySwitch.selected = TRUE;
    } else {
        mySwitch.selected = FALSE;
    }

and the two info.state lines in the changeState method, the switch works fine. It seems like the info.state setter, regardless of their bearing on the switch state, prevent the switch from switching.

Am I just being colossally negligent and not managing memory correctly?

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
    }

    // Configure the cell...
    [self configureCell:cell atIndexPath:indexPath];
    return cell;
}

- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
    InfoObject *info = [self.fetchedResultsController objectAtIndexPath:indexPath];
    cell.textLabel.text = info.name;

    // Use a custom UISwitch that holds a pointer to the row it is associated with
    NamedUISwitch *mySwitch = [[[NamedUISwitch alloc] initWithFrame:CGRectZero] autorelease];
    mySwitch.indexPath = indexPath;
    [mySwitch addTarget:self action:@selector(changeState:) forControlEvents:UIControlEventValueChanged];
    // And of course we need to know what the state is
    NSLog(@"switchState:%@",info.state);

    // Establish what position the switch should be in
    if([info.state isEqualToString:@"on"]){
        mySwitch.selected = TRUE;
    } else {
        mySwitch.selected = FALSE;
    }

    cell.accessoryView = mySwitch;
}

- (void) changeState:(id)sender {
    InfoObject *info = [self.fetchedResultsController objectAtIndexPath:((NamedUISwitch*)sender).indexPath];

    if(((NamedUISwitch*)sender).on){
        info.state = @"on";
    } else {
        info.state = @"off";
    }

    NSError *error;
    if (![self.context save:&error]) {
        NSLog(@"Whoops, couldn't save state: %@", [error localizedDescription]);
        //TODO: alertview
    }
}

Solution

  • I think that code should be:

    // Establish what position the switch should be in
        if([info.state isEqualToString:@"on"]){
            mySwitch.on = YES;
        } else {
            mySwitch.on = NO;
        }