truncated italic text in UIButton? - ios

I found a strange behaviour when dealing with UIButton with big font size :
My iPad application need to present those kind of UIButton and I found that when I apply italic property on those big font sized UIButton, the text looks truncated like below :
this is strange as my UIButton is correctly centered and big enough.
sizeToFit doesn't help.
I tried to put log to know more, and it appears that the inside size of the UILabel of the button is too tiny :
NSLog(#"Button width : %.1f, text width : %.1f", button.frame.size.width, button.titleLabel.frame.size.width);
[button.titleLabel sizeToFit];
NSLog(#"Button width : %.1f, text width : %.1f", button.frame.size.width, button.titleLabel.frame.size.width);
which gives me :
Button width : 710.3, text width : 518.0
Button width : 710.3, text width : 518.0
it is doing the same think directly in IB, when applying more than 150 px font size on an italic styled UIButton.
is there a way to fix it or is it an SDK bug ?

You can try out setting the title of the button like the following
[button setTitle:#"2 " forState:UIControlStateNormal/Highlighted/Selected];
or do the same using the .xib file associated with your ViewController.
After that, you have to set the edge insets of the title of the button, which can be done from the corresponding .xib file, or do the following:
[button setTitleEdgeInsets:UIEdgeInsetsMake(0,spacingFromLeft, 0, 0)];
The second step will ensure that the text, in this case, the string "2" remains aligned towards the center. Thus, in the leftSpacing parameter of the method UIEdgeInsetsMake(), you can set the width according to your requirements to get it aligned to the center.
I was also having the same problem and adopted this solution, which may not be the best or correct approach, but it certainly worked for me.

I think its a combination of the large font size (relative to the button/label size). When you add a space, its actually increasing the size of the UILabel.
Try [button.titleLabel adjustsFontSizeToFitWidth]. This will definitely reduce the font size (if its too large for the given frame size), but will make sure that nothing from the character gets chopped off.

Related

Prevent UILabel from clipping it's text when the font size is larger than the label height

I have a circumstance in my app whereby a label may be given a font size greater than it's height. This is to do with some rather complex architecture and layout code. Normally I would increase the label's height to accommodate the larger font but that is profoundly difficult to do in my scenario and I would rather avoid it.
The next logical thing is to turn clipsToBounds off, to allow the text sublayer to overflow the bounds of the label. Unfortunately this seems to have no effect in this case as the text is still clipped.
Am I missing something?
Looking at the documentation for UILabel:
https://developer.apple.com/documentation/uikit/uilabel/1620545-textrect
I think you need to override the method textRect(forBounds:limitedToNumberOfLines:) by explicitly increasing the rectangle returned by this method to the containing size of the label’s string rather than the bounds of the label.
(This solution does of course require you to subclass.)
Hope that helps.
You should be able to get the font height from font.lineHeight and then reduce the font size until the line height is less than the label height.
The reason (need citation) is that UILabel which is embeeded in UIButton cares extra glyph information embedded in font whereas an independent UILabel doesn't.
Solution
You can nest a separate UILabel on top of your UIButton and it will solve the problem. It's ugly but it works. There are few workarounds that you ought to try.
Workarounds
Depending on the scenario here is a small checklist that I found as accepted answer or useful for someone.
1) If you're using a UIButton Make sure you're using this method
[button setTitle forState:]
otherwise you'd need to use the following code to refresh the state
[myButton setNeedsLayout];
2) You might need to adjust your font size to fit the width of the label.
[yourLabel setAdjustsFontSizeToFitWidth:YES];
3) Although setting clipToBounds works in consecutive hierarchy, You might want not want to set individually on either Button or Label.
[yourButton setClipsToBounds:NO];
[yourButton.titleLabel setClipToBounds:NO];
There are few solutions that are pointing UIButton subclassing method which are essentially trying to add UIEdgeInset to button.

How to size UIButton to fit the text when it has constraints to another elements?

The situation is on the image below:
Position of every element below UIButton depends on the position of the UIButton or the element located directly above.
How to size it properly?
In my code I set:
eventTitleButton.setTitle("verylong text, very long text, with some of text, there is os much text, that I cannot described it in a short way", forState: .Normal)
eventTitleButton.sizeToFit()
But the result is:
What am I doing wrong?
You could add constraints on the width and/or height of your UIButton. That way, it could have width and/or height >= x (x being the minimal size you want it to have).
Then, you should not even need to call sizeToFit().

Plain text being cut off at bottom in iOS, how to fix in xCode?

I noticed in my iOS app, for text that are using a system font with size 20 pt or more, the bottom of text is being cut off.
For example, the bottom portion of the letters y, g, p, and g are being cut off.
How do I fix this in Xcode?
If your using something like a UILabel it means you will need to increase the vertical height of that element.. Either in code or in interface builder.
If you are doing it in code you can get the label to resize itself to fit the contents by calling sizeToFit..
[myLabel sizeToFit];
Alternatively you could measure the size to the string by using sizeWithAttributes: then change the size of the label accordingly.
Updating this one for Swift 3.x in a UITableViewController.
In cellForRowAtIndexPath after the problematic label is set, but before the cell is returned from the method, add a line something like this:
cell.myLabelWhoseCharactersLikegyqGetCutOff.sizeToFit()

Calculation Frame of a UILabel Subclass

The bottom line is that I'm trying to reproduce the UI that iMessage has.
For the Label:
The special padding of that type of text made me create a custom UILabel. Here's the code under drawTextInRect:
[super drawTextInRect:UIEdgeInsetsInsetRect(rect, UIEdgeInsetsMake(0, 15.0, 5.0, 15.0))];
No mystery for now.
The problem comes when my cell (that contain that label has to calculate height).
The Label gets a rounding effect on the label like so:
cell.message.layer.cornerRadius = 18;
[cell.message sizeToFit];
Apparently I can't get the proper height and width of that label. I'm using sizeToFit and then I mesure the possible sizes with "sizeWithFont:" (deprecated in iOS 7) and "boundingRectWithSize:".
The only way the text can show properly is adding manually an undetermined amount of size to height and width once the calculations are made.
The best I can get then is a screen that may look good but still has some problems and not draws properly the texts.
The link has a screen of some of the screens not showing properly.
The only answer I've been able to see looking at code from other people is that they at some point make their own calculations based on letter size.
Anyone with this problem check : https://github.com/jessesquires/MessagesTableViewController
It was the only source I could find, at the end for some cases the boundingRectWithSize is not good enough.

How do I prevent text from being cut off like in UITextView?

I have a UILabel and a UITextView both with the same text (the string "SnellRoundhand", in Snell Roundhand Bold font, point size 21). The text in the UITextView appears correctly, but the UILabel has its text cut off on the left and right sides. How do I get the text in the label to appear properly?
Some notes:
Expanding the frame of the label won't work because it might solve the cutoff issue on the right side of the text but not on the left side.
I can't take the cheap way out and center the text; the text must stay at whatever alignment it is in right now.
The reason I can't just change everything to UITextViews is because my app does some processing in the background and it crashes whenever it instantiates a UITextView. I'm hoping I can get around the issue by using UILabel instead to render the text.
In iOS 6, a very nice new feature of UILabel is that it supports attributed strings. Attributed strings can include paragraph margins. So you can add margins to your string, thus ensuring that there will be some extra space between the edges of the label and the drawing of the string.
This section of my book has sample code that adds margins to a string drawn in a UILabel:
http://www.apeth.com/iOSBook/ch23.html#_attributed_strings
If you want to run on a system earlier than iOS 6, you can subclass UILabel to force the text to be drawn inset from the edges of the label, as shown in this code (also from my book):
- (void)drawTextInRect:(CGRect)rect {
[super drawTextInRect:CGRectInset(rect, 5.0, 5.0)];
}
I don't have a good answer, but I can suggest a kludge that sorta does what you want done and might give you some useful ideas. The problem sure seems to suggest a fundamental problem with Label and TextView handling for funky fonts.
The concept is simple enough:
Size the TextField with left (or right) justification to just fit the contents.
Slightly enlarge the text field width.
Change the justification to center.
This will result in a field just wide enough to display the text without clipping (if you enlarge it the right amount). I know you said you couldn't change the text alignment, but doing it this way only moves the text a point or two and it ends up where it needs to be to display the full text. The field ends up the size, and the text in the position it ought to be. For instance:
self.textField.textAlignment = NSTextAlignmentLeft;
[self.textField sizeToFit];
CGRect frame = self.textField.frame;
frame.size.width += 4;
self.textField.frame = frame;
self.textField.textAlignment = NSTextAlignmentCenter;
This works. If it isn't useful to you directly I hope it gives you some ideas.
Something I tried that wasn't helpful was subclassing UITextField and overriding the textRectForBounds: to enlarge the area used to draw the text. I could move the text starting position slightly to the right, but it still clipped the left edge. Turning off the clipsSubviews property didn't help. Seems like Apple's problem here.
On iOS 6 the UITextView has a margin on each side, you can adjust the content inset to prevent the text from using those margins.
[textView setContentInset:UIEdgeInsetsMake(-8, -8, -8, -8)];

Resources