11

I'm developing an iOS 4 application.

I'm using this code on an UIImageView on an UITableViewCell:

cell.photo.contentMode = UIViewContentModeScaleAspectFill;
[cell.photo setClipsToBounds:YES];

My images are taller than wide, and when I set UIViewContentModeScaleAspectFill, images are scaled to fit width with UIImageView width. Doing this, the image gets bigger that UIImageView and I see it outside UIImageView.

Then, I need to use setClipsToBounds:YES to don't allow this, but now all my images lose their head.

Is there any way to use UIViewContentModeScaleAspectFill and center top left image corner with top left UIImageView corner? If I need to lose a part of image, I prefer to lose its feet that its head.

UPDATE

I'm using sdWebImage framework and I have used Vadim Yelagin answer and this is my code now:

[cell.photo setImageWithURL:[NSURL URLWithString:entry.photo]
               placeholderImage:[UIImage imageNamed:@"placeholder.png"]
                        success:^(UIImage *image) {
                            CGFloat scaleX = cell.photoBorder.bounds.size.width / image.size.width;
                            CGFloat scaleY = cell.photoBorder.bounds.size.height / image.size.height;
                            CGFloat scale = MAX(scaleX, scaleY);
                            cell.photo.frame = CGRectMake(0, 0, image.size.width * scale, image.size.height * scale);
                            cell.photo.image = image;
                        } 
                        failure:nil];

I have to wait to get all images loaded and reload move around UITableView to see the right image on the right cell (this is because images are cached and it loads faster).

Instead using cell.photo.frame and cell.photo.image I need to pass to block indexPath.row to get the right cell.

I could add a new method to UIImageView+WebCache:

- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder success:(void (^)(UIImage *image, NSInteger row))success failure:(void (^)(NSError *error))failure;
{
    [self setImageWithURL:url placeholderImage:placeholder options:0 success:success failure:failure];
}

But if I do that, I get an error here:

[self setImageWithURL:url placeholderImage:placeholder options:0 success:success failure:failure];

Because now success isn't of type (void (^)(UIImage *image))

Do you know how can I fix this problem?

VansFannel
  • 45,055
  • 107
  • 359
  • 626

2 Answers2

2

Afaik, the easiest way is to calculate the imageView's frame manually from the size of the image and the frame you want it to fit in.

Create a view with the frame you're currently specifying for your imageView, make the imageView its subview. Set view.clipsToBounds = YES.

Then when you assign an image, do something like

CGFloat scaleX = view.bounds.size.width / image.size.width;
CGFloat scaleY = view.bounds.size.height / image.size.height;
CGFloat scale = MAX(scaleX, scaleY);
imageView.frame = CGRectMake(0, 0, image.size.width * scale, image.size.height * scale);
imageView.image = image;
Vadim Yelagin
  • 3,112
  • 2
  • 17
  • 20
  • 1
    Thank you. Your solution works but I'm using sdwebimage framework, and my images load asynchronously and they are part of on UITableViewCells, so I will need to adjust your code to make it work. I'm going to update my question with your answer and write down my new problem. – VansFannel Mar 28 '12 at 16:25
  • You can try (key-value) observing `image` property of imageView and adjust the frame in your observer code. Or subclass UIImageView and override its `setImage:`. – Vadim Yelagin Mar 28 '12 at 16:33
  • I've tried to subclass it but I get another problem. I've updated my question with this new problem. – VansFannel Mar 28 '12 at 16:56
0

There is no built-in way to do this, but you can do it manually:

UIGraphicsBeginImageContext(CGSizeMake(desiredWidth, desiredHeight));

[originalImage drawAtPoint...];
...

UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
Fabian Kreiser
  • 8,307
  • 1
  • 34
  • 60
  • You create an image context using 'UIGraphicsBeginImageContext' and then draw the original image scaled up so it fills the entire context but the top left of the image is at (0|0). – Fabian Kreiser Mar 28 '12 at 15:23