Как выровнять исходные тексты в UILabels с разными размерами шрифтов на iOS?
Мне нужно выровнять исходные тексты в 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];
Этот код приводит к смещению изображения, указанного ниже.
![Misalignemnt]()
Как вы можете видеть, хотя исходные линии UILabel выровнены, исходные тексты текста смещены с небольшим отрывом. Как можно динамически выровнять исходные тексты (поскольку размер шрифта может измениться во время выполнения)?
Ответы
Ответ 1
Я использовал этот ответ в нескольких разных местах, но исходные линии иногда отображались на дисплеях Retina. Ниже приведен фрагмент ниже:
[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;
Ответ 2
Вы можете получить идеальное выравнивание по пикселям для любой пары UILabels, используя значение высоты подписи UIFont в простом вычислении. Вот как:
[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), посмотрите эту четкую, сжатую статью .
Ответ 3
Я хотел сделать это сам (сейчас) и нашел свой ответ на почти идентичном вопросе. Это не простое решение, но мы должны делать математику.
Мне нужно было только сделать это с помощью двух разных меток, и я делаю это в подклассе 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;
}