Adjust height of xib containing UIStackView when elements are hidden - ios

I have an xib containing a stackview with child stack views (following Ray Wenderlichs tutorial). I wish to hide one of the child stackviews so that the height of the xib adjusts to the visible child stackviews. However currently it remains at the original fixed height and the visible stackviews are spread across it.
Here are the settings for the top level stack view:
Can anyone advise on how to make the xib height adjust to fit the visible content size?
Edit 1:
After removing the heights of each of the child stack views and make the bottom constraint of the top level stack view >= 8 to the superview, the problem still happens but the layout has changed:
Edit 2:
After add a trailing constraint, the child stackviews no longer stretch across the xib, but the height of the xib does not compress:

Issue:
The issue is because you've fixed the bottom constraint of the StackView to the HeaderView's bottom as 8.
Now, the StackView won't be able to reduce its height according to its content.
Solution:
Make it as >= 8, i.e.
bottom >= StackView.bottom + 8
That way StackView will adjust its height as per its contents.
Edit:

Related

How adjust the dynamically the height of a view based on height of stackview?

I have a problem with one of my VC. I need to resize a view depending on the height size of the stack view because the stack view have 2 textedit but in some cases one of them it's hidden.
Here is the view that contains the stackview this one needs to adjust the height depending on the height of the stackview
Here is the stackview contents, the stackview adjust perfectly depending if one of the textedit it's hidden or not but content view not, only leave the blank space under the stackview
These are the constraints of the container view.
Any suggestion to achieve the goal (?)
Please share the screenshot for constraints so I can guide you better?
What we do is we don't give any height constraint to the stack view. The views at the top and bottom then adjust themselves when the stack changes its height due to the subview hidden/show.

"Scrollable content size is ambiguous to "ScrollView"

I am a little stuck with the ScrollView in Swift and Xcode 11.
My goal is a simple ScrollView with Labels and Textfields. Each label describes what the textfields are used for. For example there is a Label "Name", so you have to enter your name in the textfield under the label. For this I need a ScrollView because the App I am coding requires a few more information. When I am trying to put this in a ScrollView I am constantly getting the following error:
"Scrollable content size is ambiguous to ScrollView".
In order to find help I searched the internet and for example found this question: UIScrollView Scrollable Content Size Ambiguity.
Unfortunatly it didn't solve my problem. So I decided to create a small test project with the following:
- I created a project as a Single View Application
- I added a ScrollView to the ViewController
- I clicked on the constrains-Button at the canvas
- I selected 0,0,0,0 for leading/top/trailing/bottom.
- I clicked on "add 4 Constrains
- Now the warning appeared. Also the ScrollView was not resized to the ViewController... I don't know why.
- I added a UIView inside the ScrollView and set the same constrains, this time according to the ScrollView.
- The UIView (Content view) got an extra constrain: Equal width with the root view
- Now I added two Buttons, one with the text "Hello" and the other one with "world" on it.
- The "hello"-Button received the following constrains: 16 to leading, trailing and top, as well as a fixed height of 30.
- The "world"-Button got the following constrains: 16 to bottom, leading, trailing and over a 1000 so you can scroll through the ScrollView.
After all these steps the error is still there and if I run the app the "hello"-Button is at the top of the screen and the "world"-Button is at the bottom and I can't scroll.
Can maybe anyone help me fixing this issue. I am looking forward to every answer! Thank you for your help in advance!
Here is the trick that worked for me:
Add a ScrollView to your wished ViewController.
Select it in the Outline and open its size inspector.
Uncheck there the option "Content Layout Guides".
Now set leading/top/trailing and bottom constrains to 0 of the ScrollView.
Add in a UIView and constrain its leading/top/trailing and bottom also to 0.
Add an equal width constrain to the UIView. (The width needs to be equal the width of the view from the ViewController, with this way you are disabeling horizontal scrolling).
The warning will disappear if every element inside the UIView is chained vertically. This means, that the top element has a constrain to the top of the view and to the element under it and so on. The last element needs a constrain to the bottom of the view.
If you followed this steps you should be fine with ScrollViews. This way you also can add as many content as you want to the bottom and the ScrollView will extend dynamically.
I hope I explained it well enough.
It sounds like you're on the right track, and really close.
The first part is absolutely right - you add your ScrollView and pin it to zero for the top, trailing, bottom, and leading constraints. That makes it take up your whole screen.
Then you drop a plain old UIView into the ScrollView, and pin its top, trailing, bottom, and leading constraints to the ScrollView (all as zero again). Then you set the UIView to have an equal width to the ScrollView. The last thing is to set the UIView's height as equal to the ScrollView's height, but you change one thing: you set the priority of this constraint to be low (250). That's basically what allows the UIView to exceed the size of the ScrollView, so you can then scroll.
All you do then is add your buttons, etc inside the UIView, so you place them in relation to it rather than the ScrollView, and pin or align them as you wish.
Add a total of 9 constraints
1 - 4: ScrollView to Superview (leading, top, trailing & bottom)
5 - 8: Content view to Content Layout guide (leading, top, trailing & bottom)
9: Content view Width equals width to Frame Layout Guide.
But when you do this (right-click drag and drop) 7 & 8 constrains (trailing & bottom constrains to Content Layout guide) will have constant values. (check image below).
Just make them zero. Now it worked.

Dynamically sized stackView for less content

I have custom XIB's which I will be using to create my ViewController at runtime. Which all XIB's are to be included inside the ViewController will be decided at runtime.
I am using a stackView for that purpose which I have added to the storyboard and constrained it to leading-triling-top-bottom of the superView. That means the stackView will be stretched to the height of the viewController.
Now when i have few Custom Views(or XIB), say 3, it should not cover the complete screen but rather stick to it's size and be added to the stackView
But my problem arises here: Since I have constrained the stackView to complete screen(as sometimes the number of XIB can be a lot more and will surpass the size of the screen and hence I might need a scrollable stackView), it shows like this
I have found kind of a hack here but I don't think that's gonna cut
StackView's Alignment - Fill, Distribution - Equal Spacing (0)
step 1. make the bottom constraint between super view and your stack view as Equal or more
step 2.
make the height constraint to your stack view with priority 1 and constant 0
step 3.
ensure you views inside stack view layouts correctly - all edges should be installed in each views
I solved it by :
Removing the bottom constraint of the stackView
Changing the Intrinsic size under Size Inspector from System Defined to Placeholder and setting the height to 1

How to set an empty UIStackView inside a UIScrollView so that i can fill it on runtime?

I'm trying to set an empty vertical UIStackView inside a UIScrollView so that I can fill the UIStackView dynamically on runtime
I tried the solution given by apple here but when I do that, the Auto Layout tool tells me that there is a missing constraint which is either the Y position or the height of the UIStackView.
The only difference I have between my UIScrollView and the one from the example is that I don't add a button inside the UIStackView.
When I fill the UIStackView on runtime, the logs say it has to break some constraints and then the UIScrollView fills the screen all the way to the bottom, pushing other views I had there out of sight.
Is this the right way to accomplish what I want? Or is there any other solution?
EDIT:
This is what I have, the logo constraint is only aspect ratio relative to itself
Set up your constraints as you have them, but without the empty stack view in the scroll view.
Next:
add a UIStackView to the scroll view
constrain all 4 sides of the stack view to the scroll view
constrain the stack view width equal to the scroll view width
constrain the stack view height equal to the scroll view height
IB should show all constraints satisfied.
Then - and here's the key - edit the stack view's Height constraint and set it to be a Placeholder:
This Height constraint will now be removed at Build-Time. Any elements you add via code as arrangedSubviews will determine the height of the stack view, which will, in turn, define the vertical scrollable area (the .contentSize) --- all handled by auto-layout.

dynamic height of of scrollview subviews in autolayout ios

I am creating a UIScrollView from xib, in which 3 view are there 2 UIViews and in middle an UIImageView. when I am setting constraints Xcode asked to set Y position constrains. But the problem is Y position constraint is blocking Scrollview to scroll down and automatically adjusting the views which looks ugly in landscape mode.
when I am delete that constraint it ask to fix height of subview. I searched a lot but I am new in autolayout so not understanding many of solutions. any help would be great.
You have to set all the height constraints in the content view.
But you also want the height of the Content to be proportional to the screen size.
To do this assign the height constraint of the imageview [equal|proportional|a-computation-of] to the view containing the UISCrollView.
It seems weird to skip levels of herarchy when assigning constraints between two views whose are not direct ancestor/sibling of each other but within a scrollview (at least) it is perfectly acceptable.
You are basically telling the scrollview that it's content has a known size and at same time setting this content to adapt dinamically to the screen size (if the constraints of the root uiview are set correctly)
UIView1
|---UIScrollView
|---UIView2
|---UIImageView [heightConstr.constant=UIView1.height-UIView2.height-UIView3.height-margins]
|---UIView3
This is the basic idea, to be done programmatically, then you can explore other solutions.
Unfortunately the constraint system in ios pretty much sucks when it's up to more complex equations involving more views for a single constraint.
UIScrollViewcan be tricky when adding constraints. You should always add a subView that will behave as the content view for your UIScrollView and all your subsequent views will go inside this content view.
UIView1
|---UIScrollView
|---UIContentView
|---UIView2
|---UIImageView
Set your UIScrollViewconstraints as you would normally but set your content view to have leading, trailing, top and bottom to the UIScrollView but also add two more constraints which will be equal width and equal height to the viewController.view but will have a low priority (So that whichever direction your content will increase in, that constraint will break and automatically increase the content size of the scroll view by taking in the inferred height of the content view). Now go on and add constraints on all your subview as you normally would. Which i'm assuming would be:
Your topmost view will have top and leading and trailing to its superView and also a fixed height.
Your bottom view will have leading, trailing and bottom to its superView and also a fixed height.
Your UIImageViewwill have a leading, trailing and top to top most view and bottom to the bottom view.
Edit:
Here is the screenshot just in case (To show the view hierarchy with the content view's constraints in the inspector)

Resources