Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS

UIButton selected image becomes unselected if you scroll to the top or bottom of the table.

I have a UITableView of products and on each product it has a UIButton that I set as selected if a user has favourited that product but after I scroll down the table then back up to that product that UIButton is set back to unselected?

I think it has something to do with the reusable table cells (as some UIButtons aren't selected), that I have set up in UITableView but I don't understand how to make I so it stays selected if I scroll up and down the table.

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

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    if (self.products != NULL) {
        Product *product = [self.products objectAtIndex:indexPath.row];
        UIImageView *productImageView = (UIImageView *)[cell viewWithTag:100];
        NSString *image = [NSString stringWithFormat:@"http://henrysays.staging.boost.co.nz/files/images/%@", product.image];
        [productImageView setImageWithURL:[NSURL URLWithString:image]];

        UILabel *productTitleLabel = (UILabel *)[cell viewWithTag:101];
        productTitleLabel.text = product.title;

        UITextView *productTextView = (UITextView *)[cell viewWithTag:102];
        productTextView.text = product.summary;

        UIButton *button = (UIButton *)[cell viewWithTag:103];

        // If product is favourited then set the UIButton above as selected and change its image.
        if (self.favourites > 0) {
            for (Product *favProducts in self.favourites) {
                if ([product.pid isEqualToNumber:favProducts.pid]) {
                    [button setImage:[UIImage imageNamed:@"favouriteSelected"] forState:UIControlStateSelected];
                    [button setSelected:YES];
                } else {
                    [button setImage:[UIImage imageNamed:@"favourites"] forState:UIControlStateNormal];
                    [button setSelected:NO];
                }
            }
        }
    }

    return cell;
}

2 Answers

Damien Watson
Damien Watson
27,419 Points

Hey Sam,

There are a few things that might trip you up here. The button you are clicking obviously receives a click and automatically changes to selected. I would check that the correct 'product.pid' is being added into your 'self.favourites' array. This can be tricky with reusable buttons (ie how do you know what 'product' the button is in thats being clicked). I guess it comes down to what your button method is.

UIButton *button = (UIButton *)[cell viewWithTag:103];
// This just connects button to the button in the cell, doesn't tell it what product this is?

Second thing to check would be to add a break point at the 'if' statement in the 'for' loop and make sure the two numbers are what you are expecting to see.


On a side note, one thing I have found to be good practice is to use tag definitions instead of 'magic' numbers:

#define    TAG_PRODUCT_IMAGE  100
#define    TAG_PRODUCT_TITLE   101

// Then you can do:
UIImageView *productImageView = (UIImageView *)[cell viewWithTag:TAG_PRODUCT_IMAGE];

Hey Damien,

Thanks for the tip on adding the break point on the 'if' statement. Turns out the loop was unselecting the button again after it had been already been selected as it continued through the loop.

I just needed to set a 'break' after the button had been selected which fixed the problem.

Also thanks for the suggestion on using tag definitions, I will tidy that up now!

Damien Watson
Damien Watson
27,419 Points

Awesome, glad you figured it out. :)