1

In an app I've built, I had a table view showing an image to the left of each cell by running the following code inside of cellForRowAtIndexPath:

cell.imageView.image = [UIImage imageNamed:myImage];

But the image was too big, so I shrunk it:

cell.imageView.transform = CGAffineTransformMakeScale(0.3, 0.3);

This worked just fine in iOS 10. But once I upgraded to the newest Xcode with the iOS 11 SDK, the images got enormous. It turns out that that second line of code transforming the image view is now doing nothing: I can comment it out, change the 0.3's to something else, etc., and it doesn't make any difference. CGAffineTransformMakeScale still has documentation in the new Xcode, so I'm assuming it wasn't deprecated, but then why did this break with iOS 11, and how do I fix it? Any ideas? Thanks in advance! Please note, I'm using Objective-C.

Edit:

Just tried 3 changes to the code:

  1. Change the second line to cell.imageView.transform = CGAffineTransformMakeScale(0.0000001, 0.0000001);. Nothing happens (i.e., the image views and the images inside them are still just as huge).

  2. Change the second line to cell.imageView.transform = CGAffineTransformMakeScale(0, 0);. The image disappears from the image view, but the image view is still the same size, and you can tell because it still displaces the text in the cell and pushes it far to the right.

  3. Remove the first line of code (no longer assigning an image to the imageview). The imageview disappears, and the text moves all the way to the left of the cell.

Perhaps this can help shed some light on what's going on?

Viktor
  • 33
  • 6
  • Share the image – Syed Qamar Abbas Oct 28 '17 at 01:59
  • @SyedQamarAbbas, the image view is dynamic, and there are many, many images that can display to the left of the title of the table cell. Prior to iOS 11, all of them shrunk appropriately, and now none of them do. So it's not image-specific. – Viktor Oct 28 '17 at 02:36

2 Answers2

1

So if you are trying to adjust the image size to fit the imageView you should actually use the imageView's contentMode property like so:

cell.imageView.contentMode = UIViewContentModeScaleAspectFit;

or in Swift for others

cell.imageView.contentMode = .scaleAspectFit

This keeps the dimensions of the image and fits the maximum size image onto the imageView without changing the dimensions

You could also try UIViewContentModeScaleAspectFit (or .scaleAspectFill in Swift) which basically fills the dimensions of the imageView entirely, but if the picture is wider or taller than the image view it crops what can't fit.

Here are all the contentModes directly from a Obj-C and Swift source files:

typedef NS_ENUM(NSInteger, UIViewContentMode) {
UIViewContentModeScaleToFill,
UIViewContentModeScaleAspectFit,      // contents scaled to fit with fixed aspect. remainder is transparent
UIViewContentModeScaleAspectFill,     // contents scaled to fill with fixed aspect. some portion of content may be clipped.
UIViewContentModeRedraw,              // redraw on bounds change (calls -setNeedsDisplay)
UIViewContentModeCenter,              // contents remain same size. positioned adjusted.
UIViewContentModeTop,
UIViewContentModeBottom,
UIViewContentModeLeft,
UIViewContentModeRight,
UIViewContentModeTopLeft,
UIViewContentModeTopRight,
UIViewContentModeBottomLeft,
UIViewContentModeBottomRight,
};

public enum UIViewContentMode : Int {
    case scaleToFill
    case scaleAspectFit // contents scaled to fit with fixed aspect. remainder is transparent
    case scaleAspectFill // contents scaled to fill with fixed aspect. some portion of content may be clipped.
    case redraw // redraw on bounds change (calls -setNeedsDisplay)
    case center // contents remain same size. positioned adjusted.
    case top
    case bottom
    case left
    case right
    case topLeft
    case topRight
    case bottomLeft
    case bottomRight
}

EDIT:

Since I see you're also interested in changing the dimensions of the imageView itself ("to leave more room for the text") what I would suggest is actually, either in storyboard or programmatically use AutoLayout to add your own imageView and have it sized and placed how you want it, instead of using the default imageView on a cell which is meant as a convenient/standardized tool.

If you are unfamiliar this I would google for an AutoLayout tutorial. Or maybe "using AutoLayout to create custom UITableViewCell"

If you dont actually want to create your own subclass you can try setting the `cell.imageView.frame = ..." somewhere to manually resize it to what you want, then setting its content mode to make sure the image fits nicely still.

See this question: How do I make UITableViewCell's ImageView a fixed size even when the image is smaller

gadu
  • 1,816
  • 1
  • 17
  • 31
  • Yes, use on of the "fill" or "fit" values, or one of the others and set `clipsToBounds` to true. – danh Oct 28 '17 at 03:01
  • And the objective c code is `cell.imageView.contentMode = UIViewContentModeScaleAspectFit;` – danh Oct 28 '17 at 03:03
  • Thanks for your responses, @gadu and @danh. What I'm actually trying to do is not just downsize the image within the imageview but downsize the entire imageview, including the image within it. The reason the distinction matters is that this leaves more room in the rest of the cell for the text. The `cell.imageView.transform = CGAffineTransformMakeScale(0.3, 0.3);` code did both in iOS 10, but does neither in iOS 11. – Viktor Oct 28 '17 at 03:08
  • Is there an action that triggers it to downsize or you just want it to be downsized always? – gadu Oct 28 '17 at 03:12
  • I'd like it to be downsized always, so I just include that line of code in the cellForRowAtIndexPath method so that it runs for every cell. – Viktor Oct 28 '17 at 03:23
  • Can you just frame it how you want it to begin with? Then no transform. But it is puzzling that you don't see the effect of the transform. As a debug step, don't set any image. Just set the image view's backgroundColor to something that will show up like [UIColor redColor]. Maybe also set the scale to something non-square (like 0.3, 0.5), so you can see the difference clearly. – danh Oct 28 '17 at 03:24
  • Right so I edited my answer. If you want a custom sized image view I would make a custom `UITableViewCell` class and create my own imageView using auto layout so it's in the size and position you want it to be in without messing around with transforms. It's a lot better to just control the frame of the `imageView` in the first place than doing something like this – gadu Oct 28 '17 at 03:24
  • danh: just tried your suggestions. If I don't set an image, the image view goes to size 0 and the text moves all the way to the left side of the cell. I set a background color to the image view, but it doesn't show up since it's now size 0. Ditto on the non-square scale. gadu: so I could start creating my own custom classes, but I had a one-liner that used to work! Would just much rather fix the one-liner than start doing that. – Viktor Oct 28 '17 at 03:30
  • Yeah I like to create my own classes because then I get full control over how everything works/looks and it should really not take that long (still strongly recommend you do this, you'll never run into any issues like the one). The imageView on cells a is a convinience thing. But you can maybe try setting the actual frame of the cell: `cell.imageView.frame = ...` which might work? – gadu Oct 28 '17 at 03:34
  • in fact i just googled "changing size of UIImageView on standard UITableVIewCell" and found this (among others): https://stackoverflow.com/questions/2788028/how-do-i-make-uitableviewcells-imageview-a-fixed-size-even-when-the-image-is-sm check my edit – gadu Oct 28 '17 at 03:38
  • Tried `cell.imageView.frame = CGRectMake(0, 0, 2, 2);` based on your suggestion/that Stack Overflow question, which should make the image super tiny, and still the image is the same size :( – Viktor Oct 28 '17 at 03:41
  • Inside cellForRowAtIndexPath right next to the old CGAffineTransformMakeScale code. If I copy the whole method from that SO post, I get errors. – Viktor Oct 28 '17 at 03:44
  • I just edited the question with some changes I tried, which may help explain what's going on? – Viktor Oct 28 '17 at 04:02
1

Found an answer to my own question, with credit due to Paul's answer from this question: How to resize a cell.imageView in a TableView and apply tintColor in Swift

CGSize  itemSize = CGSizeMake(50, 50);
UIGraphicsBeginImageContextWithOptions(itemSize, false, 0);
CGRect  imageRect = CGRectMake(0, 0, itemSize.width, itemSize.height);
[cell.imageView.image drawInRect:imageRect];
cell.imageView.image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

I still don't know why the old CGAffineTransformMakeScale doesn't work anymore, but this gets the job done.

Viktor
  • 33
  • 6