What effect do the First Baseline and Last Baseline properties have on the subviews of a UIStackView?
Generally, can someone please illustrate the implementation of these values?
Suppose you have a two-line text view (or field or label or button) and a three-line text view, and you add them to a horizontal stack view. Do you want to align their first lines, or their last lines? That's the difference.
.FirstBaseline:
.LastBaseline:
Note: I increased the vertical content hugging and compression resistance priorities to 1000 (required) to get this to work properly.
var firstBaselineAnchor: NSLayoutYAxisAnchor
Represents the baseline for the topmost line of text in the view.
var lastBaselineAnchor: NSLayoutYAxisAnchor
Represents the baseline for the bottommost line of text in the view.
Related
I have a horizontal UIStackView which has two UILabel in it. First UILabel is multiline (two line) and other one is one line only. They both have default content compression and resistance priorities. My problem is that even there is a gap between labels, "best" word in first text goes second line. I noticed that first label doesn't goes beyond half of total width.
What I want is that second label should always show itself and first label should size It self for remaining space. If It can't fit to one line It should be two line. However, If second label is too short and first label is a long one but both of them can fit, first label should go beyond half of the width.
P.S I need to use UIStackView in this scenario because there are other cases. I know putting two label inside UIView may solve the problem.
UIStackView:
- Distribution: Horizontal
- Alignment: Center
- Spacing: 0
UILabel:
- Number of line: 2
- Line break: Word wrap
UILabel:
- Number of line: 1
View hierarchy:
Desired Result:
OR
EDIT: I calculate the width of second label and give width constraint. I think It solved my problem, I'll test a bit.
//Give specific width to second label to make first one calculate right number of lines.
if let font = UIFont(name: "Metropolis-ExtraBold", size: 15) {
let fontAttributes = [NSAttributedString.Key.font: font]
let size = (secondLabelText as NSString).size(withAttributes: fontAttributes)
secondLabel.widthAnchor.constraint(equalToConstant: size.width).isActive = true
}
To try and simplify...
Forget calculating any widths... what matters is the horizontal Content Hugging and Content Compression Resistance
Leave the left (blue) label at the defaults:
Content Hugging Priority
Horizontal: 251
Content Compression Resistance Priority:
Horizontal: 750
But set the right (orange) label to:
Content Hugging Priority
Horizontal: 1000
Content Compression Resistance Priority:
Horizontal: 1000
Results:
The only other issue would be if the text in the right-side label exceeds the full width of the view -- but you haven't indicated that you might need that much text.
You should set different horizontal content compression resistants for each of them:
For this case, the blue one(multiline) should have something less than the orange one(Singleline).
Assistive note: Multiline: 250, Singleline: 750
Orange Settings:
Blue Settings:
Note that I have set the line limit of the orange one to 0. You can set it to anything you like. But if you like to make it selfsize to anyhight taller view should have higher vertical compression resistant than 250.
First embed your multiline label inside a view and constraint the label to this view (top, leading, trailing, bottom). After that add your view with your multiline label and single line label to your stackView.
Then you can use .fillProportionally for the distribution of your UIStackView and the spacing value to specify the space between your two labels.
Make also sure to use Required (1000) for your horizontal content compression resistance priority on your right number label.
View-hierarchy:
Result:
With spacing between your labels:
When using Auto Layout to position a label, I always get very imprecise results. In the example below, I have aligned the top and left edges of a UILabel to a parent UIView:
There is empty space on all four sides of the text, but the amount of empty space at the top and bottom is especially horrible. It is very tedious to take screenshots and figure out how many points I would need to offset the constraint's constant value to make the text line up properly. Is there any way to for the UILabel to properly reflect the rendered text in its frame?
I have gone through a couple of Auto Layout tutorials such as this. However I am still not clear on what the following options do in the pin dialog
What are the differences between standard value, manual values, and canvas values?
What does the constrain to margin checkbox do?
What does align do?
What are the differences between standard value, manual values, and canvas values?
Standard value uses "the recommended spacing for constraints that specify distance between items", which is usually around 10 points.
Current canvas value copies the value from how you have the objects currently displayed on the canvas.
Manual values are whatever you want.
What does the constrain to margin checkbox do?
This constrains to a container view's margins instead of its edges. From the docs:
“Horizontal and vertical constraints to a container view can be to the margin or to the edge. Margins correspond to the values in the layoutMargins atttribute of UIView and specify recommended minimal distances between an edge of a container view and the corresponding edge of a child.”
You can set a view's margins using the layoutMargins property.
What does align do?
This creates a constraint that edges or center of one view should be aligned with edges or center of another view. For example, in a column of text views, you might want every text field to have their leading and trailing edges aligned.
As seen on the screenshot above, each top cell has few labels. The frame of the label this question concerning is highlighted with green rectangle. It shows the title of some picture/sculpture or other exhibit, so there could be quite long strings.
I would like the text of this label to be just above author label (string with font of smaller size). So, normal text is aligned from top to bottom and if text is not enough to fill all the space, the gap is at the bottom part of the label.
For this label I would like to use the opposite approach: if text is not enough, all the text at the bottom. Is there any parameter of UILabel to implement above mentioned behaviour? Or I should manually count the amount of lines and adjust the size of the label?
This is fairly easy using constraints. To get the effect you desire:
Constrain your label's position above the author label
Constrain the label's width or horizontal position
Constrain the label to a reasonable height using a greater than or equal to
Either constrain the label's total height as less than or equal to, or constrain the vertical position to something greater than or equal to.
All these constraints can be added in IB very easily, or through code. These constraints will cause the label to grow vertically to accommodate more text, and then shrink back down with less text, which will achieve the effect of having the text grow up from the bottom.
I have a view with labels stacked vertically. The design specification for the view give a vertical offset from the baseline of the text in the top label to the text in the bottom label.
However when I code for this, the size of the top UILabel will always be big enough to accomodate the descender of the top label. So I can only program the offset from the descender, not from the baseline. In the attached picture, red offset is what I want to code for, but I can only code for the green offset. Is there any way that I can get the baseline offset correct either in the xib or through code? I do not want to do this by trial and error, as that would result in the programmed offset not matching the specs.
You can do it, but easier to show you in a screen shot than to explain it:
Change "30" to whatever your specified distance is.