pegar - tipografias iphone
¿Cómo alinear las líneas de base de texto en UILabels con diferentes tamaños de fuente en iOS? (4)
Necesito alinear las líneas de base de texto en UILabels. Lo que estoy haciendo actualmente es alinear las líneas de base de UILabels que contienen el texto, y cuando el tamaño de fuente del texto en dos etiquetas es diferente, esto se traduce en una línea de base de UILabels alineada pero en una línea de base de texto mal alineada (mal alineada por un pequeño margen, pero aún así desalineado). Las etiquetas se incluyen en una subclase UIView personalizada, por lo tanto, self
refiere a la UIView que abarca.
Aquí está el código relevante
[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];
Este código da como resultado el aligmento en la imagen enlazada a continuación.
Como puede ver, aunque las líneas de base de UILabel están alineadas, las líneas de base del texto están desalineadas por un pequeño margen. ¿Cómo puedo alinear las líneas de base de texto dinámicamente (porque los tamaños de fuente pueden cambiar en tiempo de ejecución)?
Después de iOS9 . Con autolayout, UILabel tiene un ancla llamada: lastBaselineAnchor . Por ejemplo:
hintLabel.lastBaselineAnchor.constraint(equalTo: titleLabel.lastBaselineAnchor).isActive = true
Estaba buscando hacer esto por mí mismo (justo ahora) y encontré mi respuesta en una pregunta casi idéntica . Sin embargo, no es una solución simple, tenemos que hacer los cálculos.
Solo necesitaba hacerlo con 2 etiquetas diferentes y lo estoy haciendo en una subclase de 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;
}
Estaba usando esta respuesta en un par de lugares diferentes, pero las líneas de base a veces estaban fuera de un píxel en las pantallas Retina. El fragmento a continuación explica la escala de la pantalla:
[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;
Puede obtener una alineación de línea de base de píxeles perfecta para cualquier par de UILabels utilizando el valor ascendente de UIFont en un cálculo simple. Así es cómo:
[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()
se usa porque los valores de font.ascender pueden ser fraccionarios.
He probado esto en dispositivos retina y no retina, con excelentes resultados. Se ha omitido la colocación de las dos etiquetas entre sí en el eje x, ya que sus necesidades pueden variar. Si necesita una explicación rápida de lo que es el ascendente UIFont (más otra información UIFont), consulte este article claro y conciso.