How can I use AutoLayout to place view exactly above other? - ios

I have a layout which has a UIScrollView which has certain constraints with its container (the root view).
Now I want to place an UIImageView exactly above this scrollview and place a large image inside it, which should be scaled accordingly.
I set up constraints between the imageview and the scrollview to align their centers and make them equally wide and high. The image shows, what I would like to achieve.
What I would like is that the scrollview is fixed before the imageview is placed so that the scrollview determines the frame of the imageview on top, but what seems to happen is that the imageview (whose image resolution is too large for the screen) determines the frame of the scrollview, resulting in complete mayhem.
How can I make it so the scrollview gets the frame shown in the first image and the imageview is properly positioned on top of it?
EDIT: I uploaded the storyboard here (without constraints on the image view as they don't work)

Related

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.

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

Image is not working as expected with constraints

I have a root UIView (for rendering shadow) and it's content is another UIVIew that contains a UIImage and some labels at the bottom. When I look at a sample poster with my constraints set up in interface builder, it looks more or less how I want it.
In this screenshot, the DropshadowUI View holds the content and renders a shadow. The CardView holds both the UIImageView and the UILabels at the bottom. The DropshadowUI View is transparent, the CardView has a blue background and is the full height/width of the dropshadow (w/ a little bit of margin) and the UIImageView has a green background to help distinguish the views while testing. You can see that the UIImageView takes up roughly 80% of the CardView layout, which is desired. The rest of the CardView is made up of the UILabels.
When I run the app however, the constraints don't seem to be working the same way as shown in interface builder. The UIImageView stretches to take the entire height of the CardView. The UILabels are hidden from sight because of this. Judging from the green blur behind my UINavigationBar and UITabBar, it appears that the UIImageView is stretching vertically beyond the extents of the visible area, despite the image not even being that large.
The UIImageView image is set in the interface builder for now (will be set programmatically when this is working). The Content Mode is Aspect Fit. Why does the UIImageView stretch vertically? The Status label has a Bottom Space to bottom of Superview set at 8 points. The Year label's Bottom Space is constrained to the top of Status. The Movie Titles bottom is constrained to the top of Year. Movie Title has it's top constrained to the bottom of the UIImageView. The assumption was that the labels would prevent the image view from growing on the bottom, and instead getting taller by stretching the top (which is constrained to the superview views top.
Is there something wrong with my constraints? I'm still learning the auto-layout system, so if there's something in the screenshots that don't help explain my constraints, let me know what I could do to help clarify them.
Edit
I reset the UIImageView to the suggested constraints and ended up with this at runtime, despite the design-time view looking correct.
Is there a way for me to constrain the UIImageView so that the image can only grow taller, until it runs out of space to fit the rest of the content? I'm missing my bottom label here because now the image is fitting into the UIImageView but pushing everything else to far down. I'd rather it try to fill as much horizontal space as it can, until the siblings beneath it can no longer be pushed further down.
What I get, vs what i want
Select your image and go to Layout Issues tool > Reset to Suggested Constraints

How to correctly configure my stackview?

I drag a vertical UIStackView in my storyboard, I constrain it vertically and horizontally and give it fixed dimensions, 300x300.
Inside this stackview, I put:
a UIImageView (Aspect Fit)
an horizontal stackview containing two buttons
I have no problems if I equally space the content inside the main stackview, but it's not what I want.
I want the imageview to take 70% of the vertical space, leaving the other 30% to the buttons.
I tried using Fill proportionally on the main stackview, but, while in the storyboard is anything ok, when I test on simulator the two buttons totally disappear and I only see the imageview with its content.
What am I doing wrong?
I've recorded a short video
Basically you need to set the height of the image to be equal to 70% of the stackview height. Hope it'd help

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