UIButton custom font vertical alignment
A similar problem was discussed at Custom installed font not displayed correctly in UILabel. There was no solution given.
Here's the solution that worked for my custom font which had the same issue in UILabel, UIButton and such. The problem with the font turned out to be the fact that its ascender property was too small compared to the value of system fonts. Ascender is a vertical whitespace above font's characters. To fix your font you will have to download Apple Font Tool Suite command line utilities. Then take your font and do the following:
~$ ftxdumperfuser -t hhea -A d Bold.ttf
This will create Bold.hhea.xml
. Open it with a text editor and increase the value of ascender
attribute. You will have to experiment a little to find out the exact value that works best for you. In my case I changed it from 750 to 1200. Then run the utility again with the following command line to merge your changes back into the ttf file:
~$ ftxdumperfuser -t hhea -A f Bold.ttf
Then just use the resulting ttf font in your app.
OS X El Capitan
The Apple Font Tool Suite Installer doesn't work anymore on OSX El Capitan because of SIP because it tries to install the binary files into a protected directory.
You have to manually extract ftxdumperfuser
. First copy the pkg from the dmg to a local directory afterwards unpack the OS X Font Tools.pkg
with
~$ xar -xf OS\ X\ Font\ Tools.pkg
Now navigate into the folder fontTools.pkg
with
~$ cd fontTools.pkg/
Extract payload with
~$ cat Payload | gunzip -dc | cpio -i
Now the ftxdumperfuser
binary is in your current folder. You could move it to /usr/local/bin/
so that you can use it in every folder inside of the terminal application with the following.
~$ mv ftxdumperfuser /usr/local/bin/
Centering a custom UIButton title with custom font
The problem came from the custom font, that it introduced some space below characters. This post solved my problem:
UIButton custom font vertical alignment
UIButton vertical alignment doesn't work
This behavior is due to the baselineAdjustment
default property of the button's titleLabel
. If you set this to UIBaselineAdjustmentNone
, you should get the effect you're looking for.
btn2.titleLabel.baselineAdjustment = UIBaselineAdjustmentNone;
From the docs for UILabel
:
baselineAdjustment
Controls how text baselines are adjusted when text
needs to shrink to fit in the label.@property(nonatomic) UIBaselineAdjustment baselineAdjustment
Discussion
If the
adjustsFontSizeToFitWidth
property is set toYES
, this property controls the behavior of the text baselines in situations where adjustment of the font size is required. The default value of this property isUIBaselineAdjustmentAlignBaselines
. This property is effective only when thenumberOfLines
property is set to1
.
and
UIBaselineAdjustmentAlignBaselines
Adjust text relative to the position of its baseline.
Available in iOS 2.0 and later.
UIBaselineAdjustmentAlignCenters
Adjust text based relative to the center of its bounding box.
Available in iOS 2.0 and later.
UIBaselineAdjustmentNone
Adjust text relative to the top-left corner of the bounding box. This is the default adjustment.
Available in iOS 2.0 and later.
Note that the default adjustment for UILabel
differs from that of a button's titleLabel
.
How can I programmatically set the vertical alignment of a UIButton - iOS
The problem was the using
button.titleLabel.textColor = [UIColor grayColor];
instead of
[button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
Elsewhere in my code I am still having troubles vertically aligning the text, but I have got the basic example going, so I should be able to get the more complicated version going if I look at it more. Perhaps there are other methods I am using like button.titleLabel.textColor which make the vertical alignment not work...
Update
The original problem was actually because my button was too short (button height).
The word husband
is in the button, which is currently vertically aligned to the bottom. But since the height of the button is not enough, it is not obvious. Even though the default of the title insets and content insets are zero, it does not seem like the title can be flush against the bottom. It looks like about 5 pixels to me. I tested with a smaller font to make sure this is correct.
Unfortunately vertically aligning the text to the top does not seem to change anything...
Vertical alignment of iOS custom font in different languages
Your question is: "Does anyone know why this might be the case?"
The answer is that the ascender property of the Japanese font is smaller than the Classic Robot one. This can be fixed by generating a custom Japanese font that has an ascender property large enough to make it match the spacing you get from the other font. This can be done by downloading the Apple Font Tool Suite and following the instructions posted in this answer.
Also for buttons you can solve the issue by increasing the insets:
myButton.contentEdgeInsets = UIEdgeInsetsMake(15.0, 0.0, 0.0, 0.0);
You can specify a different value for each of the four insets (top, left, bottom, right). A positive value shrinks, or insets, that edge—moving it closer to the center of the button. A negative value expands, or outsets, that edge. This works for the button image and button title.
Aligning a UIButton's text?
You can use the contentHorizontalAlignment:
"The horizontal alignment of content (text or image) within the
receiver."
and the contentVerticalAlignment properties for this:
"The vertical alignment of content (text or image) within the
receiver."
Example usage:
button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
button.contentVerticalAlignment = UIControlContentVerticalAlignmentTop;
Button with Image and Text vertically aligned using autolayout constraints
Few days ago, I solved similar problem,try this
private func adjustImageAndTitleOffsetsForButton (button: UIButton) {
let spacing: CGFloat = 6.0
let imageSize = button.imageView!.frame.size
button.titleEdgeInsets = UIEdgeInsetsMake(0, -imageSize.width, -(imageSize.height + spacing), 0)
let titleSize = button.titleLabel!.frame.size
button.imageEdgeInsets = UIEdgeInsetsMake(-(titleSize.height + spacing), 0, 0, -titleSize.width)
}
call this method for each button, like
self.adjustImageAndTitleOffsetsForButton(yourButton)
Offset in custom font's vertical alignment
The problem with custom fonts is that they often have a ascender/descender.
In this case, the descender causes the issue. To solve it, we have to edit the font itself.
How can we do so?
There are several tools to edit your fonts. Since I'm working on a Mac, I'm using the Apple Font Tool Suite. Once you’ve installed this you need to open Terminal and navigate to the directory that contains your font. After that enter the following command:
ftxdumperfuser -t hhea -A d font.ttf
This will create a file called font.hhea.xml, open this new file into a text editor and adjust the values for the descender. After editing and saving enter the following command into terminal to reconstruct your Font file:
ftxdumperfuser -t hhea -A f font.ttf
Note that there are three different sets of vertical metrics in most fonts. In the OS/2 table under metrics: (1) the WinAscent, WinDescent, (2) TypoAscender, TypoDescender, and (3) in the hhea table: the Ascender, Descender and LineGap.
The commands would be:
ftxdumperfuser -t OS/2 -A d font.ttf - when finished editing: ftxdumperfuser -t OS/2 -A f font.ttf
Solely changing the descender in the hhea table will change the font for any Apple device, but not for a Windows devices. Hence it's always recommended to change all three ascenders/descender (especially hhea and TypoAscender/TypoDescender).
In case you happen to work on another operating system. Just get any tool to edit fonts and edit the given values.
coretext custom font vertical draw display not corret
Apple specifies that setting NSVerticalGlyphFormAttributeName
to anything besides horizontal is undefined on iOS. Maybe this is just some side-effect of that.
In iOS, horizontal text is always used and specifying a different value is undefined.
https://developer.apple.com/documentation/uikit/nsverticalglyphformattributename
Related Topics
Create Uiimage With Solid Color in Swift
Making Text Bold Using Attributed String in Swift
How to Iterate For Loop in Reverse Order in Swift
How to Hide the Status Bar in a Swift iOS App
Importing Project-Swift.H into a Objective-C Class...File Not Found
How to Modify Swift_Module_Name
How to Programmatically Connect to a Wifi Network Given the Ssid and Password
Understanding Performseguewithidentifier
Do Something Every X Minutes in Swift
How to Get the Day of the Week With Foundation
Replacement For Deprecated -Sizewithfont:Constrainedtosize:Linebreakmode: in iOS 7
How to Load Gif Image in Swift
Changing Root View Controller of a iOS Window
How to Reload Data in a Tableview from a Different Viewcontroller in Swift