tipos tipo poner para letras letra escribir diferente cursivas cursiva como cambiar aplicacion ios ios7 uilabel autolayout

tipo - UILabel recorta el texto en cursiva(oblicuo) en los bordes izquierdo y derecho del contenido(iOS 6+)



letra cursiva iphone instagram (3)

Problema: UILabel puede recortar caracteres en cursiva (oblicuos) e incluso scripts en los bordes izquierdo y derecho. La siguiente captura de pantalla muestra el problema. En el borde izquierdo, el descensor de la ''j'' está recortado; en el borde derecho, el ascendente de la ''l'' se recorta. Me doy cuenta de que esto es sutil, y no a todos les va a importar (sin embargo, el problema empeora con los tamaños de letra más grandes).

Aquí hay un ejemplo menos sutil usando Zapfino, tamaño 22. Note que la ''j'' en júpiter se parece casi a una ''i'':

En los ejemplos anteriores, el color de fondo de la etiqueta es naranja, el texto se deja alineado y la etiqueta mantiene su tamaño de contenido intrínseco.

Este es el comportamiento predeterminado de un UILabel y ha sido así para múltiples versiones de iOS (por lo que no estoy esperando una solución de Apple).

Lo que he intentado: establecer la propiedad clipsToBounds la etiqueta en NO no resuelve el problema. También soy consciente de que podría establecer una restricción de ancho fijo en la etiqueta para que el texto tenga más espacio en el borde posterior. Sin embargo, una restricción de ancho fijo no daría más espacio a la ''j'', en el ejemplo anterior.

Voy a responder mi propia pregunta utilizando una solución que aprovecha el diseño automático y los ajustes de alignmentRectInsets la etiqueta.


En lugar de tener que pasar por un montón de gimnasia para solucionar este tonto error de Apple (lo que hice), un truco rápido y sucio es simplemente agregar un espacio al final de la cadena para evitar que la última letra en cursiva se corte. Obviamente, no ayuda con las etiquetas de varias líneas, por desgracia, o con el descensor de la primera letra ...


La etiqueta superior muestra el comportamiento predeterminado de un UILabel cuando el texto se deja alineado y la etiqueta mantiene su tamaño de contenido intrínseco. La etiqueta inferior es una subclase simple (casi trivial) de UILabel . La etiqueta inferior no corta la ''j'' o la ''l''; en cambio, le da al texto algo de espacio para respirar en los bordes izquierdo y derecho sin que el centro alinee el texto (asco).

Aunque las etiquetas en sí no aparecen alineadas en la pantalla, su texto sí aparece alineado; y lo que es más, en IB, las etiquetas en realidad tienen sus bordes izquierdos alineados porque yo UILabel en una subclase UILabel .

Aquí está el código que configura las dos etiquetas:

#import "ViewController.h" #import "NonClippingLabel.h" @interface ViewController () @property (weak, nonatomic) IBOutlet UILabel *topLabel; @property (weak, nonatomic) IBOutlet NonClippingLabel *bottomLabel; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; NSString *string = @"jupiter ariel"; UIFont *font = [UIFont fontWithName:@"Helvetica-BoldOblique" size:28]; NSDictionary *attributes = @{NSFontAttributeName: font}; NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:string attributes:attributes]; self.topLabel.attributedText = attrString; self.bottomLabel.attributedText = attrString; }

Aquí está la implementación de la subclase NonClippingLabel :

#import <UIKit/UIKit.h> @interface NonClippingLabel : UILabel @end @implementation NonClippingLabel #define GUTTER 4.0f // make this large enough to accommodate the largest font in your app - (void)drawRect:(CGRect)rect { // fixes word wrapping issue CGRect newRect = rect; newRect.origin.x = rect.origin.x + GUTTER; newRect.size.width = rect.size.width - 2 * GUTTER; [self.attributedText drawInRect:newRect]; } - (UIEdgeInsets)alignmentRectInsets { return UIEdgeInsetsMake(0, GUTTER, 0, GUTTER); } - (CGSize)intrinsicContentSize { CGSize size = [super intrinsicContentSize]; size.width += 2 * GUTTER; return size; } @end

Sin editar un archivo de fuente, sin usar Core Text; solo una subclase de UILabel relativamente simple para aquellos que usan iOS 6+ y Auto Layout.

Actualizar:

Augie comprendió el hecho de que mi solución original evitaba el ajuste de texto para texto de múltiples líneas. drawInRect: ese problema usando drawInRect: lugar de drawAtPoint: para dibujar el texto en el método drawRect: la etiqueta.

Aquí hay una captura de pantalla:

La etiqueta superior es una UILabel vainilla UILabel . La etiqueta inferior es una etiqueta NonClippingLabel con una configuración de canaleta extrema para acomodar a Zapfino en el tamaño 22.0. Ambas etiquetas se alinean a la izquierda y a la derecha utilizando Diseño automático.


Versión Swift de NonClippingLabel con el método sizeThatFits fijo de bilobatum answer.

class NonClippingLabel: UILabel { let gutter: CGFloat = 4 override func draw(_ rect: CGRect) { super.drawText(in: rect.insetBy(dx: gutter, dy: 0)) } override var alignmentRectInsets: UIEdgeInsets { return .init(top: 0, left: gutter, bottom: 0, right: gutter) } override var intrinsicContentSize: CGSize { var size = super.intrinsicContentSize size.width += gutter * 2 return size } override func sizeThatFits(_ size: CGSize) -> CGSize { let fixedSize = CGSize(width: size.width - 2 * gutter, height: size.height) let sizeWithoutGutter = super.sizeThatFits(fixedSize) return CGSize(width: sizeWithoutGutter.width + 2 * gutter, height: sizeWithoutGutter.height) } }