Resizing subview containing image in UIStackView - ios

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

Related

Rescale UIImageView proprtionally in Launch Screen Storyboard

I have a UIImageView that needs to be centered and have a width that's equal to the screen width and some height that grows proportionally with the width. So for instance, for the iPhoneXR I have:
And on the iPad 9.7 it would be:
So basically the image just scales proportionally with each screen size. I have already figured out how to center it using constraints, but I'm lost on how to get it to scale proportionally. I've played around with the auto resizing options and constraints to no avail. I struggle so badly with these storyboards, wish I could just code it! Is this even possible in a LaunchScreen storyboard?
You can't execute any code inside launch screen. However, you can make it with constraints.
Set center equal to superview, then set width equal to superview. Now, you can add aspectRatio which is like 1:1, so you imageView height would always be equal to its width or any other ratio you want.
Example:
By adding proper constraint you will get your expected result. Add aspectRatio constraint to imageView.
All constraints as per
You can not give constraints to a view w.r.t viewController in LaunchScreen.storyboard because our view hierarchy has not loaded till that point of time.
You can give an imageView constraints w.r.t itself. CTRL drag on the imageView and select height, width or aspect ratio.
Though the recommended way will be to use another viewController that will work as LaunchScreen with some delay in segue.

How maintain a circular uiview using auto layout without fixed height and fixed width

I am having issues maintaining a circular uiimageview when using autolayout without fixed height and width.
Example with fixed height / width inside a uiview container that has a fixed height.
storyboard constraints
Circular image
in viewwillayoutsubview
profileImageView.layoutIfNeeded()
profileImageView.layer.cornerRadius = profileImageView.frame.size.height / 2
profileImageView.layer.masksToBounds = true
Example without fixed height / width inside a uiview container that has a fixed height.
Storyboard constraints
Circular image
Goal: What I am trying to achieve is create a circular uiimageview that scales for all device screen sizes. I believe the issue is that without fixed height and width my cornerRadius is not correct for a circle.
What would be the best way to achieve this without setting a fixed width and height as that does not work on all screen sizes.
The first problem is that you’re pinning your view to all the edges of its parent with a fixed margin.
That may well produce a square in your storyboard, but doesn’t necessarily on your device (it depends on if your parent is constrained as a square or not, which I can’t see in your screenshots). If the parent stretches it’s width to fit it’s own superview, but doesn’t adjust its height, then your image is stretched into a rectangle.
That looks like it is the case, as the image appears stretched horizontally.
I’d suggest you remove all constraints from your image view and start again.
Make the image have a width equal to, say, 0.8 of its superview, give it a 1:1 ratio, and center it horizontally and vertically with its parent.
The second problem, is that you may be setting the cornerRadius too early.
When the view is loaded from your Storyboard, its width and height are whatever it was in storyboard.
Once the view has been laid out in its parent, the width/height will be adjusted and you’ll be left with an incorrect cornerRadius.
To solve this, simply make sure you have a 1:1 aspect ratio constraint on the view, and set the cornerRadius in viewDidLayoutSubviews (instead of viewWillLayoutSubviews).

iOS Stackview inside ScrollView with preserve image aspect ratio

I'm having a problem with scrollable content. Basically, I want to place one ImageView and one Label on the screen with ImageView width equals screen width. height depends on intrinsic content aspect ratio (while width is always equal screen width).
The label is 20 spacing bellow ImageView. That means whole content height may less or equal or even longer than the root view. What I have tried is to put Label and ImageView inside a StackView (ImageView has Aspectfit setting), Then put StackView inside ScrollView. Set up constraints as below.
The problem is the distance between ImageView and top Superview and between ImageView and Label is too big (ideally should be 20). Is there any way to achieve the desired outcome?
PS: I have tried to set stackView distributtion but no help
tl;dr Remove the aspect ratio constraint and add a height constraint for the UIImageView.
It’s important to understand that UIImageView is basically a container that holds an image, and its dimensions don’t necessarily reflect the image’s dimensions (unless you manually make them equal). When you selected Aspect Fit as UIImageView’s Content Mode, the size of the container didn’t change to correspond the image’s size; this setting only changed the way the image is placed inside the container.
As I can see in your screenshot, the UIImageView’s height is greater than its width; furthermore, the aspect ratio is fixed by the constraint you’ve added. When you placed a landscape-oriented image inside this container, the latter left white bars on the top and the bottom of the image (just like the black bars you see when you watch a widescreen video on an old monitor). Change Content Mode to Aspect Fill or Scale to Fill to see the actual size of the UIImageView.
To fix this, remove the aspect ratio constraint and set up a fixed height for either the UIImageView or the UIStackView. If I were you, I’d probably set the UIStackView’s height equal to Safe Area so that no matter how tall the stack view is, it doesn’t go beyond the screen boundaries.

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