BlackTigerX
BlackTigerX

Reputation: 6146

UITableViewCell with UIImage, width not updating on initial displayed cells

I would like to dynamically adjust the width of a UIImage inside of a UITableViewCell, I'm using the storyboard to design the UITableViewCell, I just added a label and an image, the properties get updated correctly, I'm even loading the value of the width into the label to show that it's the correct value, for the image, I'm loading a background image that I want to repeat, but the image won't update the width initially, if I scroll up and down, the images are shown as expected, here's the code for the cellForRowAtIndexPath, I've also tried to put the code on the willDisplayCell method, same result

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"mycustomcell"];
    int r = [[data objectAtIndex:indexPath.row] intValue];
    UIImageView *img = (UIImageView *)[cell viewWithTag:2];
    img.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"some_img" ofType:@"png"]]];
    CGRect frame = img.frame;
    frame.size.width = r*16;
    img.frame = frame;

    int n = img.frame.size.width;
    UILabel *label = (UILabel *)[cell viewWithTag:1];
    label.text = [NSString stringWithFormat:@"custom %d", n];
    [cell setNeedsDisplay];
    return cell;
}

I just want this to work initially as it works after scrolling, thoughts?

Upvotes: 3

Views: 2408

Answers (2)

BlackTigerX
BlackTigerX

Reputation: 6146

argh, removing Auto Layout fixed the problem

Upvotes: 1

Rob
Rob

Reputation: 437432

The dynamic resizing of contents of a tableview cell is a well known problem. While there are kludgy workarounds, I believe proper solution depends upon whether you're using autolayout or not:

  • If using auto layout, make sure that your cell's image view has a width constraint, and then you can change the constraint's constant:

    for (NSLayoutConstraint *constraint in img.constraints)
    {
        if (constraint.firstAttribute == NSLayoutAttributeWidth)
            constraint.constant = r*16;
    }
    

    Frankly, I'd rather use a custom UITableViewCell subclass and have an IBOutlet for the width constraint (e.g. imageWidthConstraint), and it saves you from having to enumerate through the constraints to find the right one, and you can simply:

    cell.imageWidthConstraint.constant = r*16;
    
  • If not using auto layout, you should subclass UITableViewCell, use that for your cell prototype's base class, and then override layoutSubviews, and resize the image view there. See Changing bounds of imageView of UITableViewCell.

Regardless of which approach you adopt, using a UITableViewCell subclass eliminates the need to use viewForTag construct, which makes the view controller code a little more intuitive.

Upvotes: 7

Related Questions