0

Possible Duplicate:
Changing bounds of imageView of UITableViewCell

I have a custom UITableViewController, and within I am dynamically styling a UITableViewCell with style UITableViewCellStyleSubtitle. All is good, except that when a cell is re-used, its imageView property does not respect my contentMode or clipsToBounds settings. Ideally, I would prefer the content to adhere to the default size/shape (which I believe is 40x40 square).

There are other posts (links below) that suggest subclassing UITableViewCell, or re-sizing your images to fit exactly, but both these feel like workarounds and (imho) would overly-complicate my code given that I am already pulling small (non-square) images.

Suggests subclassing UITableViewCell: Changing bounds of imageView of UITableViewCell

Suggests resizing all images: UITableViewCell's imageView fit to 40x40

Example code:

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

    static NSString *kCellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier];
    if (!cell) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:kCellIdentifier];
    }

    NSString *mainText = @"mainText";
    NSString *subtitle = @"subText";

    [[cell textLabel] setText:mainText];
    [[cell detailTextLabel] setText:subtitle];

    // get album cover
    UIImage *imageForCell = [album objectForKey:@"coverImage"];

    // this is the broken part - 
    // it works upon first load, but it is NOT applied when a cell is re-used/dequeued..
    // instead, the image is displayed un-scaled and un-square
    [[cell imageView] setAutoresizingMask:UIViewAutoresizingFlexibleHeight|UIViewAutoresizingFlexibleWidth];
    [[cell imageView] setContentMode:UIViewContentModeScaleAspectFill];
    [[cell imageView] setClipsToBounds:YES];

    if (imageForCell) {

        [[cell imageView] setImage:imageForCell];

    } else {

        /* code to retrieve custom image */
    }


    return cell;
}

What gives? Is there a bug in UITableViewCell? Or is this for some reason by design?

Community
  • 1
  • 1
toblerpwn
  • 5,415
  • 8
  • 38
  • 46
  • (I suspect the `autoresizingMask` is pointless in this case, but I found a few other posts that referenced it, so I included it just to be thorough..) – toblerpwn Oct 08 '12 at 18:40
  • The answer is simply that UITableViewCell implements `-layoutSubviews`, which takes the image/text size into account. Subclassing UITableViewCell really isn't that hard and can make your code much simpler (by moving all the cell logic into a setter method or similar). If you don't like excessive subclassing, you can also put a custom view in `cell.contentView` and use autoresizing, but you'll also need your own labels there too. – tc. Oct 08 '12 at 19:33
  • @tc. - if you want to put this in to an answer, I will mark the question answered for future searchers. Thanks! – toblerpwn Oct 08 '12 at 20:16

1 Answers1

1

I'm pretty sure Apple claims ownership of textLabel, detailTextLabel, and imageView with respect to layout, so I don't think you can call this a defect.

-tableView:willDisplayCell:forRowAtIndexPath: is an API specifically for formatting the layout of a cell. You should have better luck making formatting changes there.

Didn't work despite what the doc implied.

Jeffery Thomas
  • 42,202
  • 8
  • 92
  • 117
  • 1
    I'm not sure that's sufficient — the cell will need to do a relayout if the table width changes, as might happen during screen rotation. – tc. Oct 08 '12 at 19:34
  • @Jeffrey Thomas: you seem to be right in your first paragraph, but `-tableView:willDisplayCell:forRowAtIndexPath:` doesn't work to fix the problem here unfortunately. Will go for the recommendation by @tc. - thanks both. – toblerpwn Oct 08 '12 at 20:14
  • clarification: "doesn't work" == "doesn't force the cell to respect its `clipsToBounds` or `contentMode` settings" – toblerpwn Oct 08 '12 at 20:26
  • Sorry, I shouldn't have posted without trying out a test case first. I'll update my invalid answer. – Jeffery Thomas Oct 08 '12 at 20:31