Prevent resize when setting UIImage in UIImageView - ios

I have written some auto layout code programmatically. I have successfully achieved the following layout (without an image in the image view):
There are two views, an image view followed by a single line label
The label is filled with text
The image view height and width is constrained to the label's height
The label's height is the "intrinsic height"
Everything works perfect.
When I programmatically, in response to some events, set an image in the image view, the image view is resized to fit the image, and this causes the label's height to change to match the image view, ignoring the intrinsic height of the label calculated by the text in the label.
I set the height of the label using this constraint:
self.subjectLabel.autoSetContentCompressionResistancePriorityForAxis(ALAxis.Vertical);
Maybe there is something wrong with that? Does anyone know where I have gone wrong?

I ended up working around this by resizing the UIImage using the ideas from this page: http://vocaro.com/trevor/blog/2009/10/12/resize-a-uiimage-the-right-way.
I resized the image during layoutSubviews to ensure that the frames for all the subviews has been calculated.

Related

Adding image to UIImageView in UITableViewCell modifies the image view height undesirably

I have a UIImageView inside a UITableViewCell. The cell height changes based on the number of lines of text in a UILabel using estimated row heights. I want this image to be centered vertically in the cell, with a fixed width, and height >= 40 and <=80. As the cell height increases I want the image to increase to that max height then stop, always remaining vertically centered. To do this, I added those two height constraints and the width constraint, plus constraints to the top and bottom of the cell with a constant of 5 for some padding and a priority of 250. Adding a background color to the image view you can see it is being laid out as expected. But when I set the image on the image view, the height is changing unexpectedly.
With 3 lines in the label:
without an image: image view is ~60pt tall as expected
with an image: image view is 80pt tall - expected it to be ~60
With 6 lines in the label:
without an image: image view is 80pt tall as expected
with an image: image view is 80pt tall as expected
Why is that? How can I make sure the image in the image view doesn't affect the image view size, as I want the cell height determined by the auto layout constraints to determine it?
Here's a sample project.
While I wasn't able to get the expected image view height using those auto layout constraints, I did achieve the goal by using a single height constraint and manually setting its constant in layoutSubviews of the UITableViewCell, calculated to be max(40, min(contentView.bounds.height - 5 * 2, 80)). And then added a CenterY constraint to the superview to keep it vertically centered. Now adding an image to the image view doesn't unexpectedly change the image view height.

Resizing subview containing image in UIStackView

A while ago I thought it might be a good idea to replace my own layout for a number of views inside a scrollview with a UIStackView.
But after more than a week of frustration I'm asking for help:
I'd like to place subviews like these:
inside a vertical UIStackView (alignment fill, distribution fill). The UIImageView's content mode is aspect fill, the image is set at runtime and can change at runtime (especially its aspect).
I'd like the subviews to horizontally fill the stack view and to resize vertically in order to keep the image's aspect ratio intact.
When I don't add any special constraints, I don't get layout warnings, but the subview inside my stack view doesn't resize when I change the image.
If I add an aspect constraint to the UIImageView every time the image is being set, I get a layout warning the first time I change the image and afterwards it doesn't resize the subview.
Can someone of you auto layout wizards please help me out?
You cannot set a constraint on an ImageView based on an image that will be loaded later. What you should do instead is
Set a height constraint on your ImageView
Connect an IBOutlet to this constraint
When the image is loaded, find out it's aspect ratio
Calculate the desired height since you already know the width
(stackView's width)
Set this height to your ImageView's height constraint

iOS - Make UIImageView resize to fit UILabel with AutoLayout

I'm having this issue since quite some time now and it's driving me crazy: I have a UILabel with text that can be dynamically changed, and I have a UIImageView that should act as the text's background. I would like the UIImageView to resize itself to always fit the UILabel's text.
"Paid" could become "Free", or "Payant" in French for instance, and the box behind should always resize.
Using Storyboard, I have tried adding a UIImageView with the UILabel on top of it, and setting the constraints of the UILabel to the UIImageView, but this ends up resizing the UILabel to the UIImageView's size. I cannot set a fixed width or height for the UIImageView because it should adapt.
My second try was to make a UIView, recategorize it as a UIIimageView, add the UILabel as a subview, make the UIView resize to the UILabel and add the image programatically but once again, no success.
What is the right way to do this?
For the first method, I assume you set the had the label and the image view have the same vertical and horizontal centers as well has the same height and width. The problem is the layout engine is assume the intrinsic size of the image is more important than the label. To change that you need to change hugging priority and the compression resistance of the views. Go to the size inspect of the label (picture) and increase the hugging priority to required. This will for it's height and width to be it's intrinsic height and width. You could also decrease the image view's compression resistance, so it is more amendable to being sized down.
The constraints for the label:
You can change the top and leading to place it in the appropriate spot in the view.
The constraints for the image view:

AutoLayout - Keep Ratio of Image With Horizontal Constraints (Swift Xcode 6)

I've been trying to implement a timeline of picture (as instagram or facebook).
However, I've been struggling with the ratio of the image.
Here's my xib that contains my Cell :
I want the picture to keep its ratio and to completely fill the width of the cell.
I've set 4 autolayout constraint on the UIImageView as 0-0 for horizontal constraint and 5-5 for top/bottom constraints. I've also set the ViewMode to "Aspect Fit".
I've tried different setup :
set the height of UIImageView to a specific value :
--> The width of the image is modify to keep the image ratio
don't set the height of UIImageView
--> it considers that the height is equal to 0 and therefore doesn't even display the image
set the height greater or equal to a specific value :
-- > same behavior as 1. (The width of the image is modify to keep the image ratio)
I'm loading the image from an URL so I've been using the lib Haneke (https://github.com/Haneke/HanekeSwift) with the following function :
imageView.hnk_setImageFromURL(url).
It has an automatic resize of the image and I don't know how to get the original width/height of the image to set the height manually.
Again, what I want is the picture to keep its ratio and to completely fill the width of the cell.
Anyone has a suggestion ?
Thanks a lot !
This is the setup I came up with. It's a quick and dirty demo, but I would assume you'd want the image to always be centered. You can set the Horizontal and Vertical Center Constraint in storyboard to always keep it centered
If you want it to always completely fill the view, you can replace Equal Height with Equal Width, but by doing so, the imageView will run off the screen on some sizes because of the aspect ratio constraint
I've also included screenshots of the view at different sizes

How to scale a UIImage view to a square with Autolayout inside a UIScrollView

I've been struggling to learn autolayout (finally). I want to have a vertically scrolling UIScrollView that holds all the content for the view. I want to pin a UIImage view to the top of the scrollview and keep the image a square (scaleToFill). Basically I want to do this (only I want to do it with autolayout):
I can't get the image to keep its aspect ratio while staying within the screen bounds. Whenever I add an aspect ratio constraint the imageView grows to like 600 points (the width of the png I think), but I want it to just be as wide as the screen.
I think I am setting the constraints up for the UIImageView correctly because if I get rid of the scrollView and just drop the imageViw directly on the view then it seems to do what I want it to. The trick is putting it inside the scrollView.
This is how I currently have it set up:
The 4 vertical/horizontal space constraints on the scroll view are all set to constant 0.
Since the size of the UIScrollView depends on its content, you cannot have the size of your UIImageView subview dependent on it.
You have to remove the aspect ratio constraint of the UIImageView and use a fixed width one. You can also have your UIImageView width dependent on another view in the UIScrollView which has either a fixed width or otherwise unambiguous width.
Don't forget to use Placeholder as the intrinsic size value in Interface Builder.
Hope this helps.

Resources