How to evenly space two subviews around the center of UIStackView (iOS 9)? - ios

How to evenly space two subviews around the centre of UIStackView in the vertical axis?
Currently both labels are next to the top and the bottom of the StackView. The stack view is the greyed area on the simulator screen shot.
How to make them evenly spaced?
|
|
[UILabel]
|
|
[UILabel]
|
|
I've tried different configurations, but I couldn't get the desired result.
Here is my current code:
let object = UIStackView()
object.translatesAutoresizingMaskIntoConstraints = false
object.alignment = UIStackViewAlignment.Center
object.axis = .Vertical
object.distribution = UIStackViewDistribution.EqualSpacing

Considering you have similar properties set to UIStackView (as mentioned in the question)
alignment -> Center
axis -> Vertical
distribution -> Equal Spacing
The solution can be achieved by introducing two empty views with height constraint set to 0 to both ends of UIStackView.
Explanation
On Adding two empty views of height 0, we are telling UIStackView that we have 4 views instead of 2.
Now UIStackView will add equal spacing between all the views and hence the output.
You can cross verify it by looking at the height of the UIStackView and the position of the labels.
Hope this helps !!!

In stackView attribute inspecter change spacing value from 0 to your preferred space value..

Related

change hight of the tableView cell does not work

hello guys now I have UITableViewCell should have dynamic height , this cell have 3 labels , I have added them in to stack and I added all requirements
to let tableViewCell be dynamic height
1- The code used for automatic cell height
notifications.rowHeight = UITableView.automaticDimension
notifications.estimatedRowHeight = 150
2- I have set constraints leading and trailing and bottom and top space to the superView.
3- The number of lines for each label is equal zero
this is cell before run
enter link description here
this cell after run https://ibb.co/5YCMpfK
The constraints of your tableViewCell must be like:
Properties of stackView:
Axis: Vertical
Alignment: Fill
Distribution: Fill Proportionally
Spacing: 5 (as per your requirement)
Number of lines of all 3 labels = 0
Check if your stack view doesn't have height constraint.
Check if your labels do not have any height constraint.
Give your stackview top and bottom constraints a specific value and make them greater than equal to topContraint >= 5 bottomconstraint >=5.
Change the property of stack view to Fill proportionally and give spacing according to your needs.

Label doesn't show all the text inside scrollView

I want the DecriptionLabel (the Lorem Ipsum one) to have all the text inside it visible. As you can see, it is getting trimmed.
The two buttons should be under everything else, but in the case where DescriptionLabel contains a small text, the buttons should stick to the bottom of the view.
This is why I chose a >= 20 distance between the buttons and DescriptionLabel if it makes any sense.
How can I solve the trimming of the text?
Thanks.
I was originally answering How to make button stick to bottom of scroll view if the content isn't large enough? but since it is marked as duplicate of this one I am posting my answer here. Please try to set your constraints the following way: https://imageshack.com/a/img923/6671/Txzu98.png
The trick is that you set Button.Bottom Equal To ContainerView.Bottom with lower priority (I use 750) than Button.Top Greater Than Or Equal To Label.Bottom (Here I use default 1000)
The Label has to have number of lines set to 0. The height of the button should be set by height constraint (in this case is 50). The Container View Height constraint should be with low priority (in this case 250)
You should run the code to see actual result on device or simulator. Storyboard shows it a bit differently. For the current question:
https://imageshack.com/a/img923/7276/tQeT0h.png The basic idea is the same. Button Down has the same constraints as Button from above answer without Button.Top Greater Than Or Equal To Label.Bottom. There should be fixed vertical constraint between Button Up and Button Down. I am setting Button Up with fixed Height and setting trailing and leading constraint equal to trailing and leading of Button Down. The constraint Button.Top Greater Than Or Equal To Label.Bottom is now Button Up.Top Greater Than Or Equal To Label.Bottom
Have you set numberOfLines for label to 0 (that means autosize the label according to its text length)?
You should add the following constraints:
(following in sudo code)
// Constraints for ScrollView
scrollView.top = ViewController.view.top
scrollView.leading = ViewController.view.leading
scrollView.trailing = ViewController.view.trailing
scrollView.bottom = ViewController.view.bottom
// Constraints for View
view.top = scrollView.top
view.leading = scrollView.leading
view.trailing = scrollView.trailing
view.bottom = scrollView.bottom
// Width of view
view.width = ViewController.view.width
Now you just need to make sure you have layout constraints for each child of the 'view' and it's height will be correct and display the full size of the textview.
Add the following constraint:
scrollview.contentview.height >= safearea.height
This may show an error in interface builder but works in my tests:
To remove the design time error you could set a design time intrinsic content size for the scrollview's contentview (in my case I used the safe area's height of 554):
Another option (without placeholder values in IB) is to create the following constraint...
scrollview.contentview.height = safearea.height
... and change its priority to a value lower than the label's vertical content compression resistancy.

Two labels alignment and its constraints

I have 2 labels: the description label (w/ red background) and the results label (gray text)
How do i set constraints for this example in order to have the results label with the size of its content and the description label until the results leadingAnchor? (like i have in the second row)
Objective C
[self.customTextLabel.trailingAnchor constraintLessThanOrEqualToAnchor:self.counterLabel.leadingAnchor].active = YES;
[self.counterLabel.widthAnchor constraintGreaterThanOrEqualToConstant:0].active = YES;
swift
titleLabel.trailingAnchor.constraint(lessThanOrEqualTo: counterLabel.leadingAnchor).isActive = true
counterLabel.widthAnchor.constraint(greaterThanOrEqualToConstant: 0).isActive = true
I have a solution that i think it's ugly.
self.counterLabelWidthConstraint = [self.counterLabel.widthAnchor constraintEqualToConstant:0];
self.counterLabelWidthConstraint.active = YES;
And then after i set the text:
self.counterLabelWidthConstraint.constant = [self.counterLabel sizeThatFits:CGSizeMake(CGFLOAT_MAX, self.counterLabel.height)].width;
The way to do this with auto layout is by using the contentCompressionResistancePriority of the 2 labels. Set the pririty to NSLayoutPriorityRequired for the second label and something lower like NSLayoutPriorityDefaultLow for the first label. Then, as long as the 2 labels have proper constraints anchoring them to their superview and each other, the first label should compress while the second label should not.
You just need to increase the horizontal compression resistance of the right/gray label to be higher than that of the left/red label. This tells the visual layout that, in the event that there is not enough space for both labels, the one on the left will be compressed before shrinking the label on the right. 750 is the default for all views, so just increase the right/gray label's horizontal compression resistance to 751 and you should be good to go.
Swift 5 programatically:
<#label#>.setContentCompressionResistancePriority(.required, for: .horizontal)
Labels with this property will not compress horizontally.
You can set constraints for in storyboard itself. Select Label 1 (red back ground) and label's superview set widths are equal constraint. Select Label 1 and double tap on its width constraint, from the resultant window, you could see Lable 1 width equal to superview with value constant as '1'. change '1' to 0.7 or whichever the percentage you want.

UIStackView; Equal Spacing Between & Outside Elements

UIStackView is awesome, I love Equal Spacing Distribution.
But how to achieve the same space also outside of elements dynamically?
In my case all elements will have same ratio 1:1
You can add equal spacing using the story board as shown here:
Source: https://stackoverflow.com/a/32862693/3393964
#Declan has the right idea. Here's that answer programatically where you add extra views on either side so the stack view gives correct outside spacing with any number of buttons.
stackView.alignment = .center
stackView.axis = .horizontal
stackView.distribution = .equalCentering
// Then when I add the views...
let leftView = UIView()
stackView.addArrangedSubview(leftView)
content.buttons.forEach { (button) in
stackView.addArrangedSubview(button)
}
let rightView = UIView()
stackView.addArrangedSubview(rightView)
Here's what my view looks like with 2 items using equalSpacing
And here it is with equalCentering distribution, also a nice look.
I prefer to let the UIStackView handle the spacing. Create a UIStackView with equal spacing and add two 0px wide (0px high if using a vertical stackview) transparent views to the the far sides of your stack view.
You can use constraints and give then same height and width. So when you change the dimension of anyone of the component then all components are changed with same dimension.
I think what you want is to have the same spacing outside of the stack view with the spacing outside.
What I would do is the put stack view inside another view (GRAY VIEW) and set the leading and trailing constraint of the stack view to be equal to the spacing of the stack view.
Spacing of the Stack View
Constraints of the Stack View from its super view (Gray View)

UIStackView Spacing - Don't push to top and bottom anchors

I am trying to distribute some nested stack views and I think I'm missing a property to help me align the various views the way I want them.
Here's the current output:
The issue with this is that the two arranged subviews that are added to each column (a stackview), are distributed so that the first subview aligns to the top, and the second subview aligns to the bottom (leaving a variable space in between them).
But here's what I am hoping for - always a fixed space (say 10 px) in between the first and second arranged subview in each column, and the extra space below the second arranged subview is just left to be what it needs to be.
The view is arranged as follows:
outerStackView = the green view: (20px off top, 64px off left, 20px off bottom,
64px off right - present in both screenshots but only highlighted on the top one) with properties:
outerStackView.axis = .Horizontal
outerStackView.distribution = .FillEqually
outerStackView.spacing = 10
leftStackView, middleStackView, rightStackView added to the outerStackView each with properties:
columnStackView.axis = .Vertical
columnStackView.distribution = .Fill
columnStackView.alignment = UIStackViewAlignment.Top
columnStackView.spacing = 10
Then each column has 2 stackViews inside of it, represented by the darker gray box directly around the red and blue boxes. With properties:
redBlueStackView.axis = .Horizontal
redBlueStackView.distribution = .FillProportionally
redBlueStackView.alignment = UIStackViewAlignment.Top
redBlueStackView.spacing = 4
You should pin your stack view to you containing view. That will give you a more consistent look. You can also best all three of your stack view in a horizontal stack view them selves if you want all 3 to be equal sizing. Another tip is to mess with the content hugging priority and compression resistance variables. Hope that helps let me know if you have more questions.

Resources