I have a UILabel in a collection view cell that is center aligned with number of lines = 0 and line breaks = word wrap
My text is dynamic, dependent upon requested data, so some cell's don't need two lines.
Any idea why it still wont go to the second line if needed? Getting stuck on this.
While I do not know because I do not see any code, I suggest looking at the size of the label. Are you sure the label is not getting stretched / set to a size larger then the collectionviewcell?
I think this is what you're experiencing:
I made two labels, each with:
number of lines = 0
word wrap activated
just enough x and y constraints to keep them in place on the view!
I think this is what you want:
I added constraints to each label making their width less than or equal to 300
Related
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.
I'm trying to make constraints via Snapkit in a table view cell but my problem is I need to find out which element has max y position (The lowest one).
I have an UIImageView and next to image view UILabel elements. The label text is dynamic and could be very long or very short. Below these 2 elements, I have another one that should be aligned based on the label height, either taking image view or label.
My question is how to find which element (UIIMageView, UILabel) has a bigger Y position.
To be more clear I attached a draw with simple two cases.
Set a greaterThanOrEqualTo constraint on both elements.
In "plain language":
AnotherElement.top >= ImageView.Bottom (with constant of 12, or however much space you want)
AnotherElement.top >= Label.Bottom (with constant of 12, or however much space you want)
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.
I Need a label in my UI to hold up to 32 characters without distorting, so I enabled auto shrink and changed the number of lines to 0:
heres my label on the IB:
now when I run the application it runs off the screen:
how can I make it fit accordingly?
You don't want the number of lines to be 0, because that will tell the label to use any number of lines that it needs. You also have to constrain the label's right edge to its superview's right edge, because without that, it'll run off the right side, as you can see.
remove constraints first
give the width 0 and apply width constraints . Click on the constraints change width constraint = to >= after which side you want (left or right) apply top space and (trailing space or leading space) apply two constraints.
clear the lable text.
try it and let me know after this wat is th problem.
You are on right direction. Set minimum font size and maximum font size of the label and not need to truncate characters, not need to set number of lines. Autoshrink definitely works.
I have the following cell design where the numeric label shrinks and the "Overall" label is directly underneath.
I have properly set the adjustFontSizeToFitWidth and minimumFontSize properties. The font is resizing correctly. However, anchoring the numeric label to the bottom is challenging. Particularly when the font shrinks the gap between the two labels widens and does not appear vertically centered.
I have tried sizeToFit, sizeThatFits, and using the font's pointSize. All unsuccessfully.
I am aware of sizeWithFont:minFontSize:actualFontSize:forWidth:lineBreakMode:, but don't understand why I would need it in combination with adjustFontSizeToFitWidth.
Ah, so you want to position the UILabels in the middle of the container view (both horizontally and vertically)?
I have rephrased my answer so it will make more sense to future readers.
My code is assuming that you have the 3 IBOutlets set up:
UIView *containerView; //Your nice view containing the two textfields.
UILabel *points; //The label containing the number.
UILabel *overall; //The textfield containing the text 'overall'.
You could simply set the frame of the labels after assigning the text and calling the sizeToFit.
This first line positions the UILabel points, the only change being that the y coordinate is half of containerView subtract half of the height of itself.
points.frame = CGRectMake(points.frame.origin.x, (containerView.frame.size.height / 2) - (points.frame.size.height / 2), points.frame.size.width, points.frame.size.height);
To position the overall accordingly - say there is a distance of say 6 between the number and overall labels:
int space = 6;
overall.frame = CGRectMake(overall.frame.origin.x, points.frame.origin.y + points.frame.size.height + space, overall.frame.size.width, overall.frame.size.height);
Having read your comments, I think you are after this solution. If you want both UILabels to appear in the middle; subtract (overall.frame.size.height / 2) + (space / 2) from the y value of points like so (with the code of number 2 beneath it):
int space = 6;
points.frame = CGRectMake(points.frame.origin.x, ((containerView.frame.size.height / 2) - (points.frame.size.height / 2)) - ((overall.frame.size.height / 2) + (space / 2)), points.frame.size.width, points.frame.size.height);
overall.frame = CGRectMake(overall.frame.origin.x, points.frame.origin.y + points.frame.size.height + space, overall.frame.size.width, overall.frame.size.height);
The final point will produce an output like this image. As you can see the blue line is half of the whole image, and intersects the black rectangle (which is snuggly around the two labels) at its middle point. I hope this is what you were after.
Instead of using two labels, use CATextLayer instead. You will be easily able to make one part BOLD and the other normal. plus position and adjusting size for One layer will be easy relative to placing two labels. shadow setting, line break mode, fonts you will be able to adjust everything beautifully :)