Auto Layout keeps stretching UIImageView - ios

I am using Auto layout and it's driving me crazy. I have done everything I could to prevent UIImageView from stretching all over. I have no idea why it does that. I tried using constraints, solving auto layout issues. For now, the only solution was turning the auto layout itself.
Could anyone please tell me why xcode is completely ignoring my constraints? I would expect the UIImage to stay as 320x320 when I explicitly set it as that, but noooooooo....
I want to post images, but the site won't let me, and I would like to add code to this question so that it is more specific, but there's literally no code at all. I just dragged "UIImageView" from storyboard, made it small, set constraints as is, and it's just ignoring my code.

You'll want to make sure your UIImageView is set to clip to bounds. If not, the image will spill out of the view and will appear to not stretch correctly (even though in reality it is).
In interface builder, make sure the Clip Subviews box is checked.
If you're not using interface builder, the following code will do the same thing:
yourImageView.clipsToBounds = YES;

With autolayout, the values in the Size Inspector are pretty much ignored.
You might expect that if a number is typed into the boxes on the Size Inspector, Xcode would automatically create constraints to reflect what you typed, but it doesn't. You need to create "Pin" constraints on your own for the height and width of your UIImageView.
Select the image view on your storyboard
Click the "Pin" button at the bottom-right of the storyboard screen
Type the desired size into the "Width" and "Height" fields, and make sure the boxes are checked
Click the "Add 2 constraints" button
When you are done, you should be able to see your constraints in the Size Inspector on the right side of the screen (the purple boxes)

My problem was with the ContentHuggingPriority and ContentCompressionResistancePriority.
The first controls how important it is to keep the view "hugging" the image (staying close to it and not expanding) and the latter controls how resistant to compression the view is.
We use PureLayout, so the code to fix it was:
[NSLayoutConstraint autoSetPriority:ALLayoutPriorityRequired forConstraints:^{
[myImageView autoSetContentCompressionResistancePriorityForAxis:ALAxisHorizontal];
[myImageView autoSetContentHuggingPriorityForAxis:ALAxisHorizontal];
}];
(my problem was only in the horizontal axis)
May 15, 2016: Updated to PureLayout v3 syntax. If you use a version <= 2 just put UIView instead of NSLayoutConstraint. Thanks Rudolf J!

I had the same problem. I added a UIImageView into a prototype cell and wanted to align it next to the text but it kept stretching the image when I applied the constraints. In my case, I changed the 'Mode' property for the Image View to 'Aspect Fit' and it worked fine.

You can try to add UIImageView programmatically.
Call this code in your viewDidLoad method or where you want.
UIImageView *yourImageView = [[UIImageView alloc]initWithFrame:CGRectMake(50.0f, 50.0f, 320.0f, 320.0f)]; // x and y coordinates, width and height of UIImageView
[yourImageView setImage:[UIImage imageNamed:#"your_image.png"]];
[yourImageView setContentMode:UIViewContentModeCenter]; // you can try use another UIViewContentMode
[self.view addSubview:yourImageView];

Related

How to make sure the image is allways positioned to the top?

I use UIImage to display my test image with Aspect Fit mode. I want it to be always positioned to the top and fill as much space as it can (see image below).
How to setup constraints, so that the image will be always positioned to the top (without any gap on taller devices)?
Additional info:
I'm using Xcode 7.0.1
Developing for iOS 8 and above.
I'm using auto layout.
I've tried to set " >= 0" to the bottom constraint, so that the bottom gap could get a double height, but it didn't work.
Any suggestions?
I suggest you programmatically calculate the size of the imageView and set the frame directly.
Do so in your viewWillAppear or viewDidLoad method of your viewController.
this will do the trick
UIImage *image; // yourImage
CGFloat whRatio = image.size.width/image.size.height;
if (whRatio > 1) {
// there will be borders on top -> adjust your view
imageView.frame = CGRectMake(imageView.frame.origin.x,
imageView.frame.origin.y,
imageView.frame.size.width,
imageView.frame.size.height / whRatio);
}
You might want to think about also adjusting the imageView in case the image is narrow, to prevent white spaces completely.
I think you have the correct constraints. Did you try to set the contentMode to "Scale to fill".
maybe you are using aspectFit
Here I'm adding an image showing how constraints are setup for the view that contains the image, as well for the image inside the view.
If anyone want to look at my experiments in details I've made a public repo via the link below. It includes the storyboard solution branch as well as code solution branche.
https://bitbucket.org/AndrejBB/test-layout

iOS - create UIButton manually with given size

I’ a little confused with UIView’s bounds and frame. I’m creating UIButton manually with the same size as its super view:
UIButton *button = [[UIButton alloc]initWithFrame:aView.bounds];
button.backgroundColor = [UIColor blueColor];
[aView addSubview:button];
But in the simulator the button and its super view have different size. I don’t really understand this..
(I didn't use IB to create the button because next I’d like to create a 2D array of buttons within that super view, so I think maybe it’s better to create them manually)
I strongly suspect you're putting you code in viewDidLoad before the view has has a chance to finish laying out its subviews. Move your code to viewDidLayoutSubviews instead.
You are correct to use aView.frame rather than aView.bounds. Both will give you the size (width and height of the aView) but frame gives you the position of aView in its superview. The button will need the position relative to aView not aView's superview. Bounds will give you aView's position in its own coordinate system (most likely 0, 0).
What could be happening is you are creating the button using aViews size before aView's frame has been determined. When is aView's frame being determined? Is aView being created via interface builder? When are you creating the button?
The code you provided does work - that is the correct way to make a subview the same size as its superview. There are two possible explanations for why you think that isn't happening:
You might be misinterpreting what you see in the simulator. The view you see behind the button might not be aView. I'm going to discount that possibility and go with the second possibility:
You are running that code before aView achieves its final size. In other words, you are inserting button, but then layout comes along and changes the size of aView. That change in the size of aView doesn't change the size of button, so button is left with the size aView used to have at the time you created and inserted it.

iOS 7 Autolayout doesn't work

I've been working today on this problem for a while now and i couldn't solve it. I downloaded Apple's Autolayout Guide and couldn't find an answer/solution. The problem is that I'm adding a UIImageView to my View Controller and when I change the windows form factor from 3.5 to 4 and vise versa, the image view is stretched.
To solve this, I tried many ways such as clicking on reset to suggested constraints, clear all constraints, and build my own constraints by pinning and aligning.
By aligning and pinning I set the height and width to the size as in the Interface Builder and the horizontal and vertical positions as well. Unfortunately, the image still stretches upon changing the form factor in Interface Builder. I tried to only pin the height of the UIImageView but it doesn't work.
How can i work this out?
Autolayout only deals with the frame/bounds of the UIImageView. The actual way the image is rendered is controlled via it's contentMode property. You need to set it to either UIViewContentModeScaleAspectFit or UIViewContentModeScaleAspectFill to avoid stretching.

How to prevent UIImageView from resizing with Autolayout

I'm recreating my UI with auto layout and have a navbar across the top and a 2x2 grid of UIImageViews filling the rest of the screen. I put in all the constraints so it maintains this arrangement in any orientation and it's working well when the UIImageViews don't have an image in them. When I programmatically load an image in the UIImageViews, they change size and placement even though I have constraints that should prevent this.
I have all the autoresizing masks off for everything and the UIImageViews set to Aspect fit.
This autolayout stuff is new to me, but I thought I had it working...until I put an image in there. Why would that change the size and placement of the UIImageViews?
Thanks for the help!
You can modify contraints at runtime if you link them with an outlet in your view controller.
For your case you would add a width and height constraint and link them to two outlets.
Then after you know the image dimensions you would change the constant value.
I am describing this in detail for a similar use case I had here: http://www.cocoanetics.com/2012/11/first-good-auto-layout-use-case/

UIImageView ignores changes in contentMode

I'm absolutely stumped with this sizing bug I have. I have a UIImageView and a UITableView in my view layout. The UIImageView is set to Aspect Fit in IB, and it behaves as I want it to when i set the image using IB. but when I set the image programmatically, it resizes the view incorrectly.
I've tried everything I can think of to get this to appear correctly in the simulator and nothing comes out right.
bannerView.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight);
bannerView.contentMode = UIViewContentModeScaleAspectFit;
bannerView.image = banner;
bannerView.frame = CGRectMake(0,0,320,80);
bannerView.contentMode = UIViewContentModeScaleAspectFit;
self.tableView.frame = CGRectMake(0,80,320,380);
Now the really interesting thing is that even though by the way I am constructing their frames, the tableview in this code should be directly below the image view. In reality, it is not. The table view doesnt move from where I had placed it in IB (with that exact frame size and coordinates), but the image view is way smaller for some reason.
Pleas help, this doesn't make any sense to me why this doesn't work
Ok, it seems the problem was in IB I had in the autosizing section for the view, all of the arrows were checked, when I only needed the top and left ones checked to keep it aligned

Resources