历史性问题。
lastBaselineAnchor
现在为此目的而存在。
我需要对齐 UILabels 中文本的基线。我目前正在做的是对齐包含文本的 UILabels 的基线,并且当两个标签中的文本字体大小不同时,这会导致对齐的 UILabels 基线但未对齐的文本基线(未对齐一小部分,但仍然未对准)。这些标签包含在自定义 UIView 子类中,因此
self
指的是包含的 UIView。
这是相关代码
[self.mySmallLabel sizeToFit];
[self.myBigLabel sizeToFit];
self.mySmallLabel.frame = CGRectMake(0,
self.bounds.size.height - self.mySmallLabel.bounds.size.height,
self.mySmallLabel.bounds.size.width,
self.mySmallLabel.bounds.size.height);
self.myBigLabel.frame = CGRectMake(self.mySmallLabel.frame.origin.x + self.mySmallLabel.bounds.size.width,
self.bounds.size.height - self.myBigLabel.bounds.size.height,
self.myBigLabel.bounds.size.width,
self.myBigLabel.bounds.size.height);
[self.mySmallLabel sizeToFit];
[self.myBigLabel sizeToFit];
此代码会导致下面链接的图像中的对齐。
正如您所看到的,即使 UILabel 基线对齐,文本的基线也有很小的偏差。如何动态对齐文本的基线(因为字体大小可能在运行时发生变化)?
我在几个不同的地方使用了这个答案,但基线有时在视网膜显示屏上有一个像素的偏差。下面的代码片段说明了屏幕的比例:
[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;
通过在简单的计算中使用 UIFont 上升值,您可以为任何一对 UILabel 获得像素完美的基线对齐。方法如下:
[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()
是因为 font.ascender 值可能是小数。
我已经在视网膜和非视网膜设备上对此进行了测试,结果非常好。由于您的需求可能会有所不同,因此省略了两个标签在 x 轴上的相对定位。如果您需要快速解释 UIFont 上升器是什么(以及其他 UIFont 信息),请查看这篇清晰、简洁的文章。
lastBaselineAnchor
正是为了这个目的。iOS9之后。 通过自动布局,UILabel 有一个名为:lastBaselineAnchor 的锚点。 例如:
hintLabel.lastBaselineAnchor.constraint(equalTo:
titleLabel.lastBaselineAnchor).isActive = true
我只需要使用 2 个不同的标签来完成它,并且我在 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;
}
使用自动布局,变得更加容易。
选择您想要对齐的 2 个标签,然后转到对齐工具。选择“底边”/“顶边”/基线