I would like to center a UILabel based on its glyph dimensions. When I use sizeToFit() on a label its vertical positioning in a layout is not glyph aligned -- the label appears to be lower than it should. For example, when I have label with text "]" and plug that into a horizontal UIStackView the actual glyph of ] is not vertically (y) centered with other elements in the stack. I am looking for a Swift 3 iOS 10 solution.
Related
I have a UILabel that I'm using inside a container view. I'm using AutoLayout entirely programmatically--no xib or storyboard. My UILabel constraints (no height constraint set, large fixed width, top and left edges pinned, numberOfLines = 0, bottom of superview pinned to bottom of label) work perfectly for normal (around 13 or 14 point) sized text, but at large (60 point) size text I started noticing large gaps of extra space above and below my character; in this case, the capital letter "S" that's an NSMutableAttributedString. The only attributes for this attributed string are the font name and a kerning value of 1.0. Below picture shows a magnified screenshot of my label from Pixie (white square shown is from that program) with my UILabel's backgroundColor in red:
After doing lots of research (Ignore Ascender and Descender when centering UILabel vertically?, iOS - Get the "real" height of a letter, Vertically center text in UILabel depending on actual visible letter height), it seemed the reason I was encountering this issue was because of the ascender and descender values for this font aren't getting used in this case (this is a capital "S," so it would seem I just need its capHeight value). So, I decided to constrict my label height to this value, and did so by setting a height constraint equal to its capHeight value after the "S" attributed text is set. Doing this produced the following image:
As you can see, the text is now clipped in the label. As a sort of hack, I figured I'd add some padding to counteract this, so multiplying my capHeight value by 1.1 yielded the following image:
That's fine for some padding, but now there's 4 px of extra space at the top. Granted I'm zoomed in very far, but I'm not sure why I'm seeing this—I would think that since the height constraint is set to the height of this capHeight value (which has some extra added for padding now) that the "S" would be vertically centered. I've tried calling setNeedsLayout on the label, but that didn't do anything. These are the things I would love to know:
Why is the capHeight value either not returning the correct value and/or setting the label's height constraint to this value is causing the text to get clipped?
Why do I need to add padding to the capHeight value?
Does anyone have any suggestions on how I can get this text vertically centered after I add padding and/or why it's not happening automatically? I saw this answer (https://stackoverflow.com/a/17376146/482557) but wasn't sure if that would apply here.
Thanks!
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?
here some points about using autolayout that I don't understand.
1/ I have set a constraint on the leading space and the trailing space of a label (so the horizontal size of the label should be adjusted automatically) but the label fit the size of the text. How to not autosize the label (I have seen hundreds of posts about autofit a label but nothing about not autofit).
2/ Concerning my UIScrollview, I have set up trailing space and leading space to 0 (so it should fit all the screen whatever the iPhone display size) but some margins still appears. Why ?
Thanks for your help.
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 3 UILabels drawn in storyboard positioned on top of each other.
Static UI Label 1
Dynamic UI Label 2
Static UI Label 3
Labels 1 and 3 are static and never change. Label 2 is dynamic and is always one sentence long, but could be a short or long sentence that wraps. I want Label 2 to be perfectly vertically centered between label 1 and label 3 based on how much text is there. Any ideas how to do this? Greatly appreciated!
If you're using auto layout (which is on by default), then you can just stretch the middle label until it's top and bottom are the standard distance away from the other two labels (you will see a dotted blue line when you reach that distance). This assumes that your label has a clear background, or that you don't mind seeing a tall label if it doesn't. The text will be centered vertically in this tall label regardless of the number of lines. It will also stay centered on rotation.
Add the center values of Label1 and Label3 , Divide it by 2 and make it center of label2
CGPoint point = CGPointMake(Label2.Center.x,(Label1.center.y+Label3.center.y)/2);
Label2.center = point;
That's all....