How to align two UILabels on the Y axis of the center of the first line of text - ios

please see the image below for two examples of what is to be achived
the alignment should be on the Center Y of the first lines of each UILabels and should work regardless of font size or font. currently we have implemented this with different constraints to the top of the super view for different font and font size combinations.
the constraint to align the center of the two UILabels does not work since the text of the second UILabel is not fixed and can have several lines.
also the text is dynamic, so it is not known where the text will wrap to create the first line, thus it cannot be shown in an one line UILabel with the rest of the text in another one below.
currently this is implemented using UIKit, but if there is an easy solution in SwiftUI we can put these two labels in a SwiftUI component. so a SwiftUI solution would also be welcomed.

Your comments said "it should be on the glyphs" ... but, without additional information, my guess is that "real world" usage would not really need that level of precision.
For example:
While the glyphs are not perfectly center-Y aligned, it seems unlikely you'd run into a case where the first line of the "rightLabel" is " ' " ' " or . , . , ..
This layout can be easily done with only a few constraints - no need to do any calculations:
The "Positioning" label would, of course, be set .hidden = true so it would never be seen.
If you really, really want glyph-precision, you'll need to calculate
the Glyph bounding box for the left-label
the Glyph bounding box for first line of the right-label
calculate the "character box" offsets to align the Glyph Y-centers
and then position the two labels accordingly, or use Core Text to draw the text (instead of using UILabel).
Probably more work than necessary -- unless your actual use-case demands it.

That's an interesting problem! You can try using the centerYAnchor for the label on the left, and the firstBaselineAnchor for the label on the right... that will align the center Y with the text baseline, which isn't quite what you want.
To find the correct offset to apply, you can use the information from UIFont about the size of the characters. I'd probably start with capHeight * 0.5 and see if that looks or feels right. Something like:
leftLabel.centerYAnchor.constraint(equalTo: rightLabel.firstBaseLineAnchor, constant: rightFont.capHeight * 0.5)
This is a more difficult problem in SwiftUI, I think, because resolved font metrics aren't directly available to you.

Related

Set numeric UILabel for Auto Layout to correctly compute the intrinsic content size

I have a UILabel with a font of size 50 and text 1. At runtime, its text is changed to other numbers.
If I, say, center it in its superview, the automatically detected (intrinsic content size) height is a lot bigger than the actual text, and this is because it tries not to crop other lower characters like g.
The thing is that I know I won't use other characters than digits. I also don't want to set a fixed height constraint for it.
UIFont metrics include ascender, descender, cap height, x height, etc... all of which determines how the characters fit into a container. There is a good explanation and diagram here: http://cocoanetics.com/2010/02/understanding-uifont
If you really want to get the height (and/or width) of the individual character "glyphs" you'll need to use Core Text. This will include calling CTFontGetGlyphsForCharacters() and CTFontCreatePathForGlyph() to get the "glyph path" (a CGPath object), at which point you can get the "bounding box" to determine the exact size.
Lots of discussions and example code out there... A good starting point is simply searching for CTFontCreatePathForGlyph

Align two UILabel texts

I would like to align the start of the text of two UILabels. I aligned the two UILabels (with the yellow and grey background) and used sizeToFit: to shrink the UILabels to the content but the text is not perfectly left aligned. There is a gap on the left. The gap is bigger or smaller depending on the first character. I would like to align the red lines in the following picture. There is even a small gap with the small font in the grey UILabel but it's barely visible.
With the Z character the gap is smaller but still visible by the yellow area left to the Z
A simple UILabel alignment does not help for my specific problem, because the text content is dynamic and not static. So there could be any combination depending on the data I get from the backend. Therefore I was hoping for a UIFont or UILabel attribute that could return the size of the gap based on the current rendering of the text.
I know that there are great UIFont related attributes like baseline, capHeight and ascender one can access to align text but there seems to be no attribute that would return the value of this gap on the left.
If this doesn’t need to be two UILabels, you could have one with attributed text. Then both lines would be subject to the same layout.
I haven't tried the GUI which people have been posting Screen Shots of, however... the behaviour is consistent with the very nature of typography.
The font sizes are completely different, therefore the width of an em is different, subsequently the letter-spacing is also different.
See this: http://www.w3.org/WAI/GL/css2em.htm for more information.
I know this answer doesn't give you what you have asked for, however it should explain why this is happening.
For customisation such as this (if HTML and CSS) I would use a negative / positive margin on the sub text, however seeing as you are using backgrounds use padding (or the equivalent in your GUI).
Use attributed text of UILabel
set indentation as per your requirement
ref screen shot
Select both the labels and add a constraint called align leading edges.

iOS: Modify a font height, width, and spacing independently when creating PDF

In an iOS app I need to use a specific font but each character needs to be taller, thinner, and the spacing closed up to fit correctly. Is it possible to stretch/squish a font programmatically?
When you're adding text to a PDF file there are multiple ways to influence how the text is going to appear. The most generic way (and the way that might actually be sufficient for you) is to scale the text matrix:
void CGContextSetTextMatrix ( CGContextRef c, CGAffineTransform t );
As mentioned in the comment by #mkl, you can provide a matrix that will scale up in the Y direction while scaling down in the X direction. The effect will be that the letters are stretched out vertically and squished horizontally.
Normally I would expect you don't have to touch the spacing in that case, as spacing will be "squished" together just as the other characters.
Just in case that isn't sufficient, PDF actually does provide a way to change the spacing between characters too:
void CGContextSetCharacterSpacing ( CGContextRef context, CGFloat spacing );
While Apple's description talks about "additional space" to add between characters, the PDF specification and I suspect Apple's implementation as a result allows the spacing value to be both positive and negative. A negative value would have the effect of moving the characters closer together.
Seems like the best option would be to create your own custom font.
You are able to change the kerning of your font (the space between the letters) and the thickness/thinness of the font, however you probably aren't able to edit the height of the font, unless you edit the bounding box the font is inside of to scale the letters differently.
You might also want to consider using a different font...or if you're REALLY hardcore you can edit the font yourself using photoshop/illustrator.

Spacing In VLayout

I am working inside a Tabpane and I want to have 2 buttons on the bottom-right of the tap-pane, so I thought I just add a LayoutSpacer, but this resulted in
but I wanted it to look like
How can I make my Layoutspacer "bigger"?
In Smart GWT there are different methods to set the size of the component's vertical dimension.
Try with any one
canvas.setHeight100()
canvas.setHeight("100%")
canvas.setHeight("*")
Layouts may specially interpret percentage sizes on their children, and also allow "*" as a size.

Layout UILabels with baseline offset

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.

Resources