I need to align the baselines of text in UILabels. What I\'m currently doing is I\'m aligning the baselines of UILabels containing the text, and when the text font size in t
I was using this answer in a couple of different places, but the baselines were sometimes a pixel off on Retina displays. The snippet below accounts for the screen’s scale:
[majorLabel sizeToFit];
[minorLabel sizeToFit];
CGRect changedFrame = minorLabel.frame;
changedFrame.origin.x = CGRectGetWidth(majorLabel.frame);
const CGFloat scale = [UIScreen mainScreen].scale;
const CGFloat majorLabelBaselineInSuperView = CGRectGetMaxY(majorLabel.frame) + majorLabel.font.descender;
const CGFloat minorLabelBaselineInOwnView = CGRectGetHeight(minorLabel.frame) + minorLabel.font.descender;
changedFrame.origin.y = ceil((majorLabelBaselineInSuperView - minorLabelBaselineInOwnView) * scale) / scale;
minorLabel.frame = changedFrame;
You can get pixel-perfect baseline alignment for any pair of UILabels by using the UIFont ascender value in a simple calculation. Here's how:
[majorLabel sizeToFit];
[minorLabel sizeToFit];
CGRect changedFrame = minorLabel.frame;
changedFrame.origin.y = ceilf(majorLabel.frame.origin.y + (majorLabel.font.ascender - minorLabel.font.ascender));
minorLabel.frame = changedFrame;
ceilf()
is used because the font.ascender values may be fractional.
I've tested this on both retina and non-retina devices, with excellent results. Positioning the two labels relative to each other on the x-axis has been omitted, as your needs may vary. If you need a quick explanation of what the UIFont ascender is (plus other UIFont info) check out this clear, concise article.
With Autolayouts, its much more easier. Select the 2 labels you wish to align and goto the Align tool. Select "Bottom Edges"/ "Top Edges" / Baseline
I was looking to do this myself (just now) and found my answer on an almost identical question. It's not simple solution though, we have to do the math.
I only needed to do it with 2 different labels and I'm doing it in a subclass of UIView
.
- (void)layoutSubviews {
[majorLabel sizeToFit];
[minorLabel sizeToFit];
CGRect changedFrame = minorLabel.frame;
changedFrame.origin.x = majorLabel.frame.size.width;
changedFrame.origin.y = (majorLabel.frame.size.height + majorLabel.font.descender) - (minorLabel.frame.size.height + minorLabel.font.descender);
minorLabel.frame = changedFrame;
}
After iOS9. With autolayout, UILabel has an anchor called: lastBaselineAnchor. For example:
hintLabel.lastBaselineAnchor.constraint(equalTo: titleLabel.lastBaselineAnchor).isActive = true