I currently have a Stack View setup with a bunch of different objects inside of it, and I'm trying to add a view to it.
The view will have a dynamic number of labels added inside of it programmatically at run-time.
When I put the view inside of the stack view, I get errors with the constraints, which get fixed by adding a height constraint.
However, I don't know the height of the view initially so I can't constrain this.
Is there any way to have a UIView inside of a StackView auto-resize based on it's content size? I thought this would be automatic, but when I don't put a height constraint, the view doesn't show up
You don't have to put a content view inside the stackview to add the elements to it , you need to hook the stackview with only ( leading , trailing , top) constraints to the superView
then add elements with
stack.addArrangedSubview(view)
the most important thing is that the elements you add must have an intrinstic content-size like label and button , and if not then add a height with
someView.heightAnchor.constraint(equalToConstant:<#setValue#>).isActive = true
with distribution set to Fill
Steps to add custom UIView with dynamic height inside UIStackView
Add UIStackView to superview in IB and add top, bottom, leading and trailing constraints.
In case IB is throwing any error for constraint, just set intrinsic size for UIStackView as PlaceHolder with some dummy size. This will fix UIStackView position in IB but this will automatically change at run time as per auto layout.
Create instance of CustomUIView as below
Bundle.main.loadNibNamed(nibName, owner: self, options: nil).first as! CustomUIView
Add UIView to UIStackView as below.
stackView.addArrangedSubview(customView)
This will add custom UIView to UIStackView and it will expand/collapse as per xib content and constraints. Just make sure your xib has proper constraints as per auto layout guidelines.
Related
I have 2 UIViews with labels inside. The UIView should expand depending on the content in the label. Following is the layout:
Both of the above views can expand depending on the content in the label. I have tried to set layout with autolayout but the width is always fixed. Following are my constraints for second view:
First view constraints:
It looks like your first view is missing a leading constraint to the label inside.
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.
I have a screen where the main view has a UIScrollView which contains a UIView which in turn contains 3 UIViews placed vertically, I have set the constraints accordingly, trying setting contentSize in both viewDidLoad and viewDidLayoutSubviews, all to no avail. I have created a sample project with the issue I'm facing at https://github.com/modsoussi/ScrollViewTest.
I'm surprised Interface Builder isn't showing a Constraints error or warning...
When using auto-layout, the contents of the scroll view define the contentSize. That means the contents (in your case, a single UIView holding 3 smaller UIViews) must have a constraint to the Top, Leading, Trailing and Bottom of its superview (the scroll view)... and it must have a Height and Width.
In your storyboard, delete the "Center Vertically" constraint, and add a Height constraint (of 1000) to the "content" view. Then delete your scrollView.contentSize = ... line from code. Run the app, and you should have no problem scrolling.
I am trying to make a view containing an UIScrollView. This UIScrollView contains 3 UIViews. The last one contains another UIStackView I wanted to fill at runtime.
Here an image of the storyboard :
But when I add content at runtime in the second UIStackView, the ScrollView's height remains the same.
The second UIStackView is defined as the first one with:
Axis : vertical
Alignment : Fill
Distribution : Equal Spacing
Then I use :
mStackView.addArrangedSubview(matProgress)
The result below :
What's the way to have the bottom view and the ScrollView stretch to fit the content.
The layout can be done with auto-layout and constraints.
The key points are:
do not set height constraints on either StackView
set the "Main" StackView Distribution to Equal Spacing
set the "Main" StackView Leading, Trailing, Top and Bottom constraints to its Superview (which is the ScrollView)
you do need to also set a width constraint on the "Main" StackView to control the horizontal contentSize
The only quirk will be on startup. If you have NO content in the bottom / inner StackView, it will still "exist" in the Main StackView and take up space. There is a trick to get around that, but it must be done in code.
You can see a working example here: https://github.com/DonMag/StackyScrolly
If you have UIScrollView and the child views with auto-layout. Setting programmatically the height of the scrollview will stretch the inside views to comply with the auto-layout.
So, you get by code the height of the third view and set the UIScrollView height to view1.height + view2.height + expectedThirdViewHeight.
Hi I am developing small IOS application in which I am using scrollview with auto-layout.Inside scroll I am adding two more views. I am using IB and auto-layout constraints. I am adding two views in side one after another in vertical manner. I have added outer constraints like trailing, leading, top, bottom space. I also added height constraints for both views. Till this everything is working fine.
But my view1 has some dynamic content. For that reason I want to make height constraint greater than equal to instead of equal to.
So how to resolve this problem. Need some help. Thank you.
You should follow the approach below.
First of all, here are some important things about scroll Views which are important for auto layout:
UIScrollView changes its bounds automatically.
UIScrollView needs a content View(in UI) for getting content size for scrolling which works smoothly for auto layout.
UIScrollView's top and bottom constraint should connected to top and bottom layout guide (For most of the cases, not all).
As per your problem:
First Approach: You have UIScrollView, so just insert one UIView inside it and consider it as Content View. After that put your two UIViews inside the UIView (Content View).
So the Hierarchy is: MainView --> UIScollView --> UIView (ContentView) --> firstView & Second View. Now we are going to give constraints to all of them.
For UIScrollView, connect TOP and BOTTOM constraints to TOP & Bottom Layout Guide and LEADING and TRAILING to the Main View.
For UIView (Content View) it is very important to give constraints LEADING, TRAILING, TOP, BOTTOM to the UIScrollView and to give the explicit height (normal height constraint) to your contentView which is appropriate for scrolling (e.g 1200). Also make it horizontally center in container.
Now give constraints to your first view: LEADING, TRAILING, TOP to ContentView and give explicit height (normal height constraint). Don't try to modify it in greater than equal right now - we will do this later. Then, give constraint to second view Leading, Trailing to ContentView, Top to FirstView, Bottom to Content View and Explicit Height (what ever you want). Now, try to modify the Height constraint of first view from equal -> greater than equal - it will definitely work.
Second Approach (Easy and Simple): After giving constraint as per first point, for changing height of first View dynamically you can create an IBOutlet of height constraint of first view to your class and as per your requirement you can change the constraint's constant value (as per you want the height of first view) in any method or button action so it will change in run time. You can also consider it is a fine trick when you want to hide your views so just change their Height constraint's constant to 0 so it will hide and at the time of unhide, again set the constant value of same to desired value so you can also easily play with hide and unhide functionality of view which is little bit difficult in auto layout from other ways.
I would make this constraint as type equals and give it low priority. Then, during adding dynamic content, you may just add another constraint with higher priority.
If you load this UIView from xib just make sure you provide constraint with higher priority.