¿Ignora Ascender y Descender al centrar UILabel verticalmente?

Estoy usando AutoLayout para colocar algunas tags en el centro vertical de una celda. El text está en todas las mayúsculas, pero el UILabel en cuestión, incluso cuando se aplica sizeToFit , deja espacio debajo del text, que se parece mucho a las queues en letras como minúsculas y, p y q . Como estoy centrado verticalmente, esto está causando un desplazamiento y significa que el text aparece unos píxeles más alto de lo que debería hacer.

Otra pregunta puede ser: ¿puedo hacer que una fuente ajuste de forma inteligente su centro vertical dependiendo de si contiene algún personaje que use el ascendente o descendente?

Por ejemplo, la cadena "abbaba" no necesita el descendente, mientras que la cadena "oyyoyo" no necesita el ascendente. Las strings en todos los casquillos tampoco necesitan el descensor. Si yo centro verticalmente "oyyoyoyo" parecerá demasiado bajo.

introduzca la descripción de la imagen aquí

Gracias, Abhinit , por tu respuesta.

También estaba buscando esto, así que me gustaría publicar aquí las restricciones exactas que necesita para aplicar para alinear los texts a su gusto.

Esta image de Wikipedia muestra las diferentes secciones de tamaño de una fuente.

introduzca la descripción de la imagen aquí

Por lo tanto, hay muchas forms de alinear una label dependiendo de si desea alinearse con la altura del ascenso, la altura del casquillo, la altura x, la línea base o la altura del descenso.

Digamos que tiene una label contiene text en mayúsculas y viewAbove como "HELLO" y desea alinear con la vista viewAbove para viewAbove altura y alinear con viewBelow a la línea de background.

Tu harías:

 let font = label.font let ascenderDelta = font.ascender - font.capHeight LayoutHelper() .addViews([ "label":label, "viewAbove":viewAbove, "viewBelow":viewBelow ]) .withMetrics(["ascenderDelta":ascenderDelta]) .addConstraints([ // -- Here the constraints to align to cap height -- "X:label.top == viewAbove.bottom - ascenderDelta", "X:label.baseline == viewBelow.top", ...other constraints... ]) 

Nota: en el ejemplo estoy usando mi class de utilidad LayoutHelper , pero espero que la idea sea clara.

Acerca de una label de "alignment automática":

Pensaré en hacer una label "inteligente" que se ajuste a la línea apropiada dependiendo de si contiene descendientes, ascendentes, mayúsculas, etc.

Podría hacerlo usando inserciones negativas en drawTextInRect (como aquí , pero, por ejemplo, usando insets = {-ascenderDelta, 0, font.descender, 0} ). Pero eso recortaría a cualquier ascendente / descendiente en caso de que tuviera. Preferiría alinearme con las tapas sin recortar ningún ascendente posible.

Puede usar las properties 'capHeight' y 'xHeight' en UIFont para get la altura correcta y usarla para dimensionar la UILabel.

Por supuesto, esto supone que usted sabe con certeza si una cadena sería minúscula o mayúscula solamente. Si no, puede anular setText en una UILabel y verificar cada vez que se invoca la function.

También me gustaría pensar en profundizar en CoreText e implementar algo como esto http://www.zsiegel.com/2012/10/23/Core-Text-Calculating-line-heights/

Tuve el mismo problema y lo solucioné subclassando UILabel y cambiando su método de extracción:

 - (void)drawRect:(CGRect)rect { CGRect capCentenetworkingRect = CGRectMake(rect.origin.x, (self.font.leading-self.font.capHeight)*0.5f, rect.size.width, rect.size.height); [super drawTextInRect:capCentenetworkingRect]; } 

En mi caso, necesitaba centrar en mayúsculas porque el centrado vertical de la UILabel es siempre algunos píxeles apagado. Si necesita centrarse verticalmente en letras minúsculas con descendente, puede cambiar el rectángulo a:

 CGRectMake(rect.origin.x, (self.font.leading-self.font.xHeight)*0.5f+self.font.descender, rect.size.width, rect.size.height)