uiappfonts ttf otf font custom ios objective-c fonts uilabel

ios - ttf - uiappfonts



Cambio dinámico de tamaño de fuente de UILabel (13)

Actualmente tengo un UILabel :

factLabel = [[UILabel alloc] initWithFrame:CGRectMake(20, 100, 280, 100)]; factLabel.text = @"some text some text some text some text"; factLabel.backgroundColor = [UIColor clearColor]; factLabel.lineBreakMode = UILineBreakModeWordWrap; factLabel.numberOfLines = 10; [self.view addSubview:factLabel];

A lo largo de la vida de mi aplicación de iOS, factLabel obtiene un montón de valores diferentes. Algunos con oraciones múltiples, otros con solo 5 o 6 palabras.

¿Cómo puedo configurar el UILabel para que el tamaño de la fuente cambie para que el texto siempre se ajuste a los límites que definí?


Aquí está el código de relleno de una subclase de UILabel que implementa cambios de tamaño de letra animados:

@interface SNTextLayer : CATextLayer @end @implementation SNTextLayer - (void)drawInContext:(CGContextRef)ctx { // We override this to make text appear at the same vertical positon as in UILabel // (otherwise it''s shifted tdown) CGFloat height = self.bounds.size.height; float fontSize = self.fontSize; // May need to adjust this somewhat if it''s not aligned perfectly in your implementation float yDiff = (height-fontSize)/2 - fontSize/10; CGContextSaveGState(ctx); CGContextTranslateCTM(ctx, 0.0, yDiff); [super drawInContext:ctx]; CGContextRestoreGState(ctx); } @end @interface SNAnimatableLabel () @property CATextLayer* textLayer; @end @interface SNAnimatableLabel : UILabel - (void)animateFontToSize:(CGFloat)fontSize withDuration:(double)duration; @end @implementation SNAnimatableLabel - (void)awakeFromNib { [super awakeFromNib]; _textLayer = [SNTextLayer new]; _textLayer.backgroundColor = self.backgroundColor.CGColor; _textLayer.foregroundColor = self.textColor.CGColor; _textLayer.font = CGFontCreateWithFontName((CFStringRef)self.font.fontName); _textLayer.frame = self.bounds; _textLayer.string = self.text; _textLayer.fontSize = self.font.pointSize; _textLayer.contentsScale = [UIScreen mainScreen].scale; [_textLayer setPosition: CGPointMake(CGRectGetMidX(_textLayer.frame), CGRectGetMidY(_textLayer.frame))]; [_textLayer setAnchorPoint: CGPointMake(0.5, 0.5)]; [_textLayer setAlignmentMode: kCAAlignmentCenter]; self.textColor = self.backgroundColor; // Blend text with background, so that it doens''t interfere with textlayer text [self.layer addSublayer:_textLayer]; self.layer.masksToBounds = NO; } - (void)setText:(NSString *)text { _textLayer.string = text; super.text = text; } - (void)layoutSubviews { [super layoutSubviews]; // Need to enlarge the frame, otherwise the text may get clipped for bigger font sizes _textLayer.frame = CGRectInset(self.bounds, -5, -5); } - (void)animateFontToSize:(CGFloat)fontSize withDuration:(double)duration { [CATransaction begin]; [CATransaction setAnimationDuration:duration]; _textLayer.fontSize = fontSize; [CATransaction commit]; }


Aquí hay una extensión de Swift para UILabel. Ejecuta un algoritmo de búsqueda binario para cambiar el tamaño de la fuente en función del ancho y la altura de los límites de la etiqueta. Probado para trabajar con iOS 9 y autolayout.

USO: Donde <label> es su UILabel predefinido que necesita cambiar el tamaño de la fuente

<label>.fitFontForSize()

De manera predeterminada, esta función busca dentro del rango de tamaños de fuente de 5pt y 300pt y establece la fuente para que se ajuste a su texto "perfectamente" dentro de los límites (precisa dentro de 1,0pt). Puede definir los parámetros para que, por ejemplo, busque entre 1pt y el tamaño de letra actual de la etiqueta con precisión dentro de 0.1pts de la siguiente manera:

<label>.fitFontForSize(1.0, maxFontSize: <label>.font.pointSize, accuracy:0.1)

Copie / pegue el siguiente código en su archivo

extension UILabel { func fitFontForSize(var minFontSize : CGFloat = 5.0, var maxFontSize : CGFloat = 300.0, accuracy : CGFloat = 1.0) { assert(maxFontSize > minFontSize) layoutIfNeeded() // Can be removed at your own discretion let constrainedSize = bounds.size while maxFontSize - minFontSize > accuracy { let midFontSize : CGFloat = ((minFontSize + maxFontSize) / 2) font = font.fontWithSize(midFontSize) sizeToFit() let checkSize : CGSize = bounds.size if checkSize.height < constrainedSize.height && checkSize.width < constrainedSize.width { minFontSize = midFontSize } else { maxFontSize = midFontSize } } font = font.fontWithSize(minFontSize) sizeToFit() layoutIfNeeded() // Can be removed at your own discretion } }

NOTA: cada una de las llamadas layoutIfNeeded() se puede eliminar a su propia discreción


Es 2015. Tuve que ir a buscar una publicación de blog que explicara cómo hacerlo para la última versión de iOS y XCode con Swift para que funcione con varias líneas.

  1. establecer "Autoshrink" en "Tamaño de fuente mínimo".
  2. establecer la fuente al tamaño de letra más grande que desee (elegí 20)
  3. Cambie "Saltos de línea" de "Ajustar palabra" a "Truncar cola".

Fuente: http://beckyhansmeyer.com/2015/04/09/autoshrinking-text-in-a-multiline-uilabel/


Esta solución funciona para multilínea:

Después de seguir varios artículos y de requerir una función que escalara automáticamente el texto y ajustara el recuento de líneas para que encajara mejor dentro del tamaño de etiqueta dado, escribí yo mismo una función. (es decir, una cuerda corta encajaría bien en una línea y usaría una gran cantidad del marco de la etiqueta, mientras que una fuerte larga se dividiría automáticamente en 2 o 3 líneas y ajustaría el tamaño en consecuencia)

Siéntase libre de reutilizarlo y modificarlo según sea necesario. Asegúrese de llamar después de que viewDidLayoutSubviews haya finalizado para que se haya establecido el marco de etiqueta inicial.

+ (void)setFontForLabel:(UILabel *)label withMaximumFontSize:(float)maxFontSize andMaximumLines:(int)maxLines { int numLines = 1; float fontSize = maxFontSize; CGSize textSize; // The size of the text CGSize frameSize; // The size of the frame of the label CGSize unrestrictedFrameSize; // The size the text would be if it were not restricted by the label height CGRect originalLabelFrame = label.frame; frameSize = label.frame.size; textSize = [label.text sizeWithAttributes:@{NSFontAttributeName:[UIFont systemFontOfSize: fontSize]}]; // Work out the number of lines that will need to fit the text in snug while (((textSize.width / numLines) / (textSize.height * numLines) > frameSize.width / frameSize.height) && (numLines < maxLines)) { numLines++; } label.numberOfLines = numLines; // Get the current text size label.font = [UIFont systemFontOfSize:fontSize]; textSize = [label.text boundingRectWithSize:CGSizeMake(frameSize.width, CGFLOAT_MAX) options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading) attributes:@{NSFontAttributeName : label.font} context:nil].size; // Adjust the frame size so that it can fit text on more lines // so that we do not end up with truncated text label.frame = CGRectMake(label.frame.origin.x, label.frame.origin.y, label.frame.size.width, label.frame.size.width); // Get the size of the text as it would fit into the extended label size unrestrictedFrameSize = [label textRectForBounds:CGRectMake(0, 0, label.bounds.size.width, CGFLOAT_MAX) limitedToNumberOfLines:numLines].size; // Keep reducing the font size until it fits while (textSize.width > unrestrictedFrameSize.width || textSize.height > frameSize.height) { fontSize--; label.font = [UIFont systemFontOfSize:fontSize]; textSize = [label.text boundingRectWithSize:CGSizeMake(frameSize.width, CGFLOAT_MAX) options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading) attributes:@{NSFontAttributeName : label.font} context:nil].size; unrestrictedFrameSize = [label textRectForBounds:CGRectMake(0, 0, label.bounds.size.width, CGFLOAT_MAX) limitedToNumberOfLines:numLines].size; } // Set the label frame size back to original label.frame = originalLabelFrame; }


Extensión simple, simplemente ajuste el máximo y el mínimo

extension UILabel { func adjustFontSizeToHeight() { // Initial size is max and the condition the min. for var size = 25 ; size >= 4 ; size-- { let font = UIFont(name: self.font!.fontName, size: CGFloat(size))! let attrString = NSAttributedString(string: self.text!, attributes: [NSFontAttributeName : font]) let rectSize = attrString.boundingRectWithSize(CGSizeMake(self.bounds.width, CGFloat.max), options: .UsesLineFragmentOrigin, context: nil) if rectSize.size.height <= self.bounds.height { self.font = font break } } } }


No es un poco sofisticado, pero debería funcionar, por ejemplo, digamos que quieres tapar tu uilabel a 120x120, con un tamaño máximo de fuente de 28:

magicLabel.numberOfLines = 0; magicLabel.lineBreakMode = NSLineBreakByWordWrapping; ... magicLabel.text = text; for (int i = 28; i>3; i--) { CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:(CGFloat)i] constrainedToSize:CGSizeMake(120.0f, CGFLOAT_MAX) lineBreakMode:NSLineBreakByWordWrapping]; if (size.height < 120) { magicLabel.font = [UIFont systemFontOfSize:(CGFloat)i]; break; } }


Según la respuesta de @Eyal Ben Dov, es posible que desee crear una categoría para que sea flexible y se pueda utilizar en otras aplicaciones suyas.

Obs .: he actualizado su código para hacer compatible con iOS 7

-Archivo de cabecera

#import <UIKit/UIKit.h> @interface UILabel (DynamicFontSize) -(void) adjustFontSizeToFillItsContents; @end

-Fichero de implementación

#import "UILabel+DynamicFontSize.h" @implementation UILabel (DynamicFontSize) #define CATEGORY_DYNAMIC_FONT_SIZE_MAXIMUM_VALUE 35 #define CATEGORY_DYNAMIC_FONT_SIZE_MINIMUM_VALUE 3 -(void) adjustFontSizeToFillItsContents { NSString* text = self.text; for (int i = CATEGORY_DYNAMIC_FONT_SIZE_MAXIMUM_VALUE; i>CATEGORY_DYNAMIC_FONT_SIZE_MINIMUM_VALUE; i--) { UIFont *font = [UIFont fontWithName:self.font.fontName size:(CGFloat)i]; NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:text attributes:@{NSFontAttributeName: font}]; CGRect rectSize = [attributedText boundingRectWithSize:CGSizeMake(self.frame.size.width, CGFLOAT_MAX) options:NSStringDrawingUsesLineFragmentOrigin context:nil]; if (rectSize.size.height <= self.frame.size.height) { self.font = [UIFont fontWithName:self.font.fontName size:(CGFloat)i]; break; } } } @end

-Uso

#import "UILabel+DynamicFontSize.h" [myUILabel adjustFontSizeToFillItsContents];

Aclamaciones


Simplemente envíe el mensaje sizeToFit a UITextView. Ajustará su propia altura para ajustarse a su texto. No cambiará su propio ancho u origen.

[textViewA1 sizeToFit];


Versión Swift:

textLabel.adjustsFontSizeToFitWidth = true textLabel.minimumScaleFactor = 0.5


minimumFontSize ha quedado en desuso con iOS 6. Puede usar minimumScaleFactor .

yourLabel.adjustsFontSizeToFitWidth=YES; yourLabel.minimumScaleFactor=0.5;

Esto se ocupará de su tamaño de fuente de acuerdo con el ancho de la etiqueta y el texto.


Linea sola:

factLabel.numberOfLines = 1; factLabel.minimumFontSize = 8; factLabel.adjustsFontSizeToFitWidth = YES;

El código anterior ajustará el tamaño de fuente de su texto hasta (por ejemplo) 8 tratando de ajustar su texto dentro de la etiqueta. numberOfLines = 1 es obligatorio.

Múltiples líneas

Para numberOfLines > 1 hay un método para determinar el tamaño del texto final a través de los métodos de adición de UIKit de NSString , por ejemplo:

CGSize lLabelSize = [yourText sizeWithFont: factLabel.font forWidth:factLabel.frame.size.width lineBreakMode:factLabel.lineBreakMode];

Después de eso, puede simplemente cambiar el tamaño de su etiqueta utilizando el resultado de lLabelSize etiqueta, por ejemplo (suponiendo que solo cambiará la altura de la etiqueta):

factLabel.frame = CGRectMake(factLabel.frame.origin.x, factLabel.frame.origin.y, factLabel.frame.size.width, lLabelSize.height);

ios 6

Linea sola:

A partir de iOS6, minimumFontSize ha quedado obsoleto. La línea

factLabel.minimumFontSize = 8.;

puede ser cambiado a:

factLabel.minimumScaleFactor = 8./factLabel.font.pointSize;

ios 7

Múltiples líneas

A partir de iOS7, sizeWithFont queda obsoleto. El caso de Multiline se reduce a:

factLabel.numberOfLines = 0; factLabel.lineBreakMode = NSLineBreakByWordWrapping; CGSize maximumLabelSize = CGSizeMake(factLabel.frame.size.width, CGFLOAT_MAX); CGSize expectSize = [factLabel sizeThatFits:maximumLabelSize]; factLabel.frame = CGRectMake(factLabel.frame.origin.x, factLabel.frame.origin.y, expectSize.width, expectSize.height);


Línea única : hay dos formas, simplemente puede cambiar.

1- Pragmáticamente (Swift 3)

Solo agregue el siguiente código

yourLabel.numberOfLines = 1; yourLabel.minimumScaleFactor = 0.7; yourLabel.adjustsFontSizeToFitWidth = true;

2 - Usando el inspector de Atributos de UILabel

i- Select your label- Set number of lines 1. ii- Autoshrink- Select Minimum Font Scale from drop down iii- Set Minimum Font Scale value as you wish , I have set 0.7 as in below image. (default is 0.5)


Versión de Swift 2.0:

private func adapteSizeLabel(label: UILabel, sizeMax: CGFloat) { label.numberOfLines = 0 label.lineBreakMode = NSLineBreakMode.ByWordWrapping let maximumLabelSize = CGSizeMake(label.frame.size.width, sizeMax); let expectSize = label.sizeThatFits(maximumLabelSize) label.frame = CGRectMake(label.frame.origin.x, label.frame.origin.y, expectSize.width, expectSize.height) }