views:

649

answers:

1

I'm creating a button for each cell row in a tableview. The button acts as switch to add the selected row as 'favorite' in NSUserDefaults. My problem is that whenever I press this button, a new one get drawn on top of the old one. How do I release/reuse it right? This is what my cellForRowAtIndexPath method looks like:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"cellID";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;

    } 

    UIImage *favOn = [UIImage imageNamed:@"favOn.png"];
    UIImage *favOff = [UIImage imageNamed:@"favOff.png"];                   
    UIButton *favButton = [[UIButton alloc] initWithFrame:CGRectMake(230, 0, 54, 54)];


    favButton.tag = viewTag;

    [favButton setImage:favOff forState:UIControlStateNormal];
    [favButton setImage:favOn forState:UIControlStateSelected];

    if([self getFavState:viewTag]) {

        [favButton setSelected:YES];
    }
    else {
        [favButton setSelected:NO];
    }

    [favButton addTarget:self action:@selector(favButtonSwitch:) forControlEvents:UIControlEventTouchUpInside];
    [favButton setBackgroundColor:[UIColor clearColor]];
    [cell.contentView addSubview:favButton];
    [favButton release];

    return cell;
}

Further I use three different methods for selections of the buttons:

- (void) setFavState:(BOOL)state withId:(NSString *)uid {

    NSUserDefaults *savedData = [NSUserDefaults standardUserDefaults];
    [savedData setBool:state forKey:uid];   
}

- (BOOL) getFavState:(NSString *)uid {

    NSUserDefaults *savedData = [NSUserDefaults standardUserDefaults];
    return [savedData boolForKey:uid];
}

- (void) favButtonSwitch:(id) sender {
    NSInteger senderId = [sender tag];
    NSString *senderString = [NSString stringWithFormat:@"%i", senderId];

    NSLog(@"sender:%i",senderId);

    [self getFavState:senderString];

    if([self getFavState:senderString]) {

        [self setFavState:NO withId:senderString];
    }
    else {
        [self setFavState:YES withId:senderString];
    }

    [self.tableView reloadData];
}
A: 

You seem to be creating a new button with new images every time, even if it was retrieved from the cache. Move the code for creating a button with images into the code that creates a cell for the first time.

if (cell == nil) {
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    // Move all the image and button creation in here...
} 
willcodejavaforfood
Thanks, that works only partially, because it doesn't update the select states visually when I tap/click the button. I see that it indeed was activated by the senderId but no instant selected/unselected uicontrol states(, because it is then cached from the previous start?)
hecta
Well you need to put the code for setting the state of the buttons outside that block then. Does that make sense? Maybe repost your code as it is now?
willcodejavaforfood
I have it fixed now, my biggest mistake was [self.tableView reloadData] in the button-toggle method. I replaced it with a real toggle like this: if([sender isSelected]) ... [sender setSelected:NO]
hecta
Hey that's great :)
willcodejavaforfood