Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIViewContentModeScale mode of the cell image change silently after the cell is touched(highlighted)

EDIT:

I get the issue fixed by create a customize cell.(However, still have another questions.) But why the default cell does not work is still a mystery...

Cory 's answer did not fix the issue but clipsToBounds is really a point and I appreciated his continuous help. So I give him the bounty but not accept his answer as the answer. The answer still in the wind....

================================

I set the UIViewContentModeScale mode of the cell image to AspectFill (left image) and the image was correctly displayed(Fill the image view but keep the aspect). However, after touch and hold on the cell, image's will change: the imageView's frame and contentViewMode are changed. (see the first cell of the left image below )

This is really wired and I can believe such as basic thing could goes wrong so there must be some stuff I was missing out.

Environment: Xcode 4.3 iOS5.1 simulator & device. enter image description here

UPdate:

I set the UIViewContentMode using the inspector of the storyboard.

And by the way ,I used SDWebImage/UIImageView+WebCache.h.

UPdate2:

I set explicitly the content mode in the code but issue still there. [cell.imageView setContentMode:UIViewContentModeScaleAspectFill];

update4:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"AlbumCell"];

    if(cell == nil){
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"AlbumCell"];

    }
    //[cell.imageView setContentMode:UIViewContentModeScaleAspectFill];
    //[cell.imageView setClipsToBounds:YES];
    [self configureCell:cell atIndexPath:indexPath];
    return cell;
}
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
    Album *album = [self.fetchedResultsController objectAtIndexPath:indexPath];
    cell.textLabel.text = [album.title description];    
    cell.detailTextLabel.text = [self.userVisiableDateFormatter stringFromDate:album.releaseDate];


    //[cell.imageView setContentMode:UIViewContentModeScaleAspectFill];
    [cell.imageView setImageWithURL:[NSURL URLWithString:album.coverThumbnailUrl]
                placeholderImage:[self placeHolderImage]];

}

enter image description here

like image 655
pierrotlefou Avatar asked Jul 24 '12 06:07

pierrotlefou


3 Answers

I was able to find a couple of different things that might be the problem.

First it try setting the clipsToBounds property:

img1.contentMode = UIViewContentModeScaleAspectFill; 
img1.clipsToBounds = YES;

The second is:

The reason you don't see a difference between those modes is that the UITableViewCell automatically sizes its image view to fit the aspect ratio of the image. The content modes only come into play when the view's aspect ratio is different from the image's.

Either override layoutSubviews in your custom UITableViewCell class or create an image view yourself (don't use the one that the table view cell provides).

EDIT 1:

After looking at your code the problem may lie in how your handling your cell configuration. Pointers maybe getting released when they shouldn't. Try these 2 options:

Option 1: Keep your current method of passing off configuration to a new method.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"AlbumCell"];

    if(cell == nil){
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"AlbumCell"];

    }

    return [self configureCell:cell atIndexPath:indexPath];
}

- (UITableViewCell*)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell* returnCell = cell;

    Album *album = [self.fetchedResultsController objectAtIndexPath:indexPath];
    returnCell.textLabel.text = [album.title description];    
    returnCell.detailTextLabel.text = [self.userVisiableDateFormatter stringFromDate:album.releaseDate];


    [returnCell.imageView setContentMode:UIViewContentModeScaleAspectFill];
    [returnCell.imageView setClipsToBounds:YES];

    [returnCell.imageView setImageWithURL:[NSURL URLWithString:album.coverThumbnailUrl]
                placeholderImage:[self placeHolderImage]];

    return returnCell;
}

Option 2: (my recommendation) Configure the cell in the delegate method. It's ok to do this here and it's not bad practice. This is delegate method is there to configure the cell.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"AlbumCell"];

    if(cell == nil){
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"AlbumCell"];

    }


    Album *album = [self.fetchedResultsController objectAtIndexPath:indexPath];
    cell.textLabel.text = [album.title description];    
    cell.detailTextLabel.text = [self.userVisiableDateFormatter stringFromDate:album.releaseDate];

    [cell.imageView setContentMode:UIViewContentModeScaleAspectFill];
    [cell.imageView setClipsToBounds:YES];

    [cell.imageView setImageWithURL:[NSURL URLWithString:album.coverThumbnailUrl]
                placeholderImage:[self placeHolderImage]];


    return cell;
}
like image 85
random Avatar answered Sep 28 '22 08:09

random


set the same image for highlighted state also .

like image 36
Vinodh Avatar answered Sep 28 '22 08:09

Vinodh


it could be the case that you need to set your auto-resizing (or struts & springs, if you have learned that terminology).

in an app in which i have a custom cell with an image on the left similar to yours, i have my autoresizing set up as in the following picture:

enter image description here

note that i have it set up so that the size remains constant within the cell frame, and that the top, bottom and left size are commanded to hug those edges with that much gap on each side.

aside from that, i believe you are right that aspectFill is the choice for that setting. clipToBounds really shouldn't matter; it will only be necessary if that view were a subview of another view in which it was supposed to appear where it's size was larger than the view it is a subview of.

like image 33
john.k.doe Avatar answered Sep 28 '22 08:09

john.k.doe