I have a height constraint for a horizontal stackView within a UIView that I change based on the content of a view. If the text of a label in the stackView is beyond a certain size, the constraint moves to 116.33, otherwise it is 96. This horizontal stackView is pinned to the top of this UIView.
At runtime, I get a warning of this constraint being broken, but I get the intended operation:
If I remove the constraint "Horizontal Stack View.top = top", no warnings occur, but I don't get the intended operation:
I have tried commensurately changing the height of the UIView via locationView.frame.size.height as well as by adding another constraint to the view, specifically, and adjusting that in the same way I adjust the stackView height constraint, but the resulting behavior is essentially the same.
This is the document outline:
How can I get the intended effect, and also make XCode happy?
Here is how I read your 4 conflicting constraints:
Horizontal StackView height is 96.
The Horizontal StackView and Vertical StackView are aligned at their tops.
The Horizontal StackView and Vertical StackView are aligned at their bottoms.
Vertical StackView height is >= 136.
So the heights of the StackViews are the same because of the alignment of their tops and bottoms. But they each have their own constraint setting their height.
I suggest getting rid of one of the StackView height constraints.
Related
So i created a simple UIView. I added two UIButtons. I have added them in a StackView. I have put the Alignment of the stackview to fill in xcode attributes inspector and the distribution to fill equally and the spacing to 50. Then i added a height constraint of 300 to the stackview and i added a custom font as well to the buttons as well as three constraints. One for the stackview bottom as you see at the screenshot, one for the trailing and one for the leading constraint. I haven't put a top constraint yet. When i change to different devices through xcode the buttons are not centered. I added the top constraint but i guess because of the height constraint at the stackview there is an issue and all constraint become red when i change to another device than the initial i created the stackview. If i move for example to Iphone SE the buttons move to the top side i guess because of the bottom constraint... So is there a way to center the stackview with the buttons as i change to different devices? Any help appreciated.
For a stack view to be centered you needs leading, trailing and vertical centering constraints, stack view will have automatic height based on buttons heights and vertical spacing, no need for bottom constraint
My Goal
To make a reverse scroll view that changes height with the height of the vertical stack (the contents of which will be controlled programatically)
What I have tried
Setting the stack view, Scroll view and content view the same heights. I am not sure how to change the simulated size of the view controller with it
Note: I am using Storyboard not swift UI, I have researched this and all I can find are tutorials for how to do this in SwiftUI
I wanted it to be controlled by the height of the stack view, so it does not scroll when there isn't anything to scroll to, if this is wrong please correct me and give me some guidance
The ViewController now:
Can anyone help?
If I understand your question correctly, I had a similar issue recently.
My solution was:
Fully constrain the UIScrollview within the superview
Place a UIView inside the UIScrollView. Align the UIView's leading and trailing constraints to the UIScrollView's content layout guide AND frame layout guide ( =0, or whatever margin you need). Align the UIView's top and bottom constraints to the UIScrollView's content layout guide ( =0 ). Constrain the UIView's height to be equal to the height of the UIScrollView's frame layout guide with a priority of 500 (make sure the multiplier is 1 as Autolayout might set it to something else). These constraints should be added by control dragging from the UIView to the UIScrollView's layout guides within the document outline (I had problems if I didn't add them this way). This fixes the widths, but if the UIView's height needs to expand then the equal height constraint can break allowing it to grow outside the UIScrollView's frame, triggering scrolling.
Place your UIStackView inside the UIView. Align the UIStackView leading and trailing constraints to the superview (the UIView), or use a horizontally centred within superview constraint. Constrain the UIStackView to be vertically centred within the superview (again, the UIView). Align the bottom constraint of the UIStackView to be >=0 relative to the superview (UIView). Thus, when the UIStackView is smaller than the UIView (and UIScrollView) it remains centred and doesn't scroll. As soon as the UIStackView (and UIView) exceeds the size of the UIScrollView, the >=0 constraint between UIStackView and UIView bottom takes precedence over the equal height constraint between the UIView and UIScrollView frame layout guide, forcing scrolling.
In step 3, I think you might be better served by aligning the top of the UIStackView to the top of the UIView, rather than having the UIStackView vertically centred. The bottom constraint should still be >=0. I didn't try this myself but it should still work.
If you need the UIScrollView itself to increase in size, then pin its top and bottom within the superview to the minimum size you want it to be, with a low priority such as 250, then add >= constraints to fix the outer limit of where you want it to be. For example, Constrain the bottom of the UIScrollView to be =100 from the bottom safe area guide with a priority of 250, then constrain it to also be >= 25 from the bottom safe area with the default priority of 1000. In this case the first constraint to break should be the bottom of the UIScrollView which will allow the UIScrollView to grow until it hits the bottom >=25 constraint, at which point the UIView to UIScrollView_frame_layout_guide equal height constraint will break triggering scrolling.
I hope that makes sense (and that I haven't missed anything)!
PS I also ran into a problem with the UIStackView contents (programatically defined in my case) resizing in odd ways which seemed to be fixed by changing content mode from "Scale to Fill" to "Redraw". I set distribution to "Fill Equally" or "Fill Proportionally" depending on the look I wanted (I had two such views).
I have a horizontal StackView with distribution as "fill equally". It has 3 labels.
I want one of the labels to have dynamic height.
When I set the number of number of lines to 0 for that label, it ends up breaking the constraint the spacing constraint at runtime.
All these horizontal stackviews make a one vertical stackview.
I have tried setting lower vertical hugging priority and higher resistance priority to the multiline label
Also it behaves like this in the XIB
Before changing the number of lines
After changing the number of lines
You do not need to set Content Hugging and Compression resistance property to achieve that effect.
Horizontal Stack Views: Set Alignment "Fill" & Distribution "Fill Equally"
Vertical Stack View: Set Alignment "Fill" & Distribution "Fill"
Set Label Lines to 0.
Set Top, Bottom, Leading Constraint for Vertical Stack View.
Set all constraints for UIStackView.
Update the UIStackview height constraints constant value based on UILabel text height
Not Directly answering the question rather on how to control the dynamic height of UIStackView.
Vertical Stack View. Make it free of height like no bottom constraints or no height constraints.
Contents(like view) are fixed height.
Both Alignment & Distribution of UIStackView will "fill"
now show or hide the contents then Stactview height will dynamically change.
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.
I have uiview with constraints for vertical centring inside superview and for width and height. On rotation of device uiview should always be in center, but I need to have ability to change width of uiview but its position should not be changed. I have tried:
- to add leading and trailing constraints but in such case width of uiview is no changing at all
- to add constraints for width that it should be greater and less but in such case width is not changed, uiview just moved
If I am understanding the issue correctly, you probably assigned too many constraints on the view so the autolayout system has a conflict and removes some of the constraints and then the ones you want there don't have any effect. I suggest you look into debug output window to see warnings about constraint conflicts and which ones are being removed.
What you want is: remove all the constraints you added on this view, then constraint its leading to the left side of the super view, constraint it to horizontal center inside superview. This way the uiview will be centered, and will resize accordingly. You can also constraint height or constraint the aspect ratio between width and height. What you definitely don't want is to constraint the height and width directly.