Cambiar el tamaño de la fuente para llenar UITextView?

¿Cómo establecería el tamaño de fuente del texto en una UITextView de manera que ocupe toda la UITextView? Me gustaría que el usuario escriba su texto, luego haga que el texto complete todo UITextView.

¡Cualquier ayuda es apreciada!

He convertido la respuesta de dementiazz a Swift:

func updateTextFont() { if (textView.text.isEmpty || CGSizeEqualToSize(textView.bounds.size, CGSizeZero)) { return; } let textViewSize = textView.frame.size; let fixedWidth = textViewSize.width; let expectSize = textView.sizeThatFits(CGSizeMake(fixedWidth, CGFloat(MAXFLOAT))); var expectFont = textView.font; if (expectSize.height > textViewSize.height) { while (textView.sizeThatFits(CGSizeMake(fixedWidth, CGFloat(MAXFLOAT))).height > textViewSize.height) { expectFont = textView.font!.fontWithSize(textView.font!.pointSize - 1) textView.font = expectFont } } else { while (textView.sizeThatFits(CGSizeMake(fixedWidth, CGFloat(MAXFLOAT))).height < textViewSize.height) { expectFont = textView.font; textView.font = textView.font!.fontWithSize(textView.font!.pointSize + 1) } textView.font = expectFont; } } 

Esto, en una categoría en UITextView, debería hacer el truco. Por qué necesitas el fudgefactor, mira esta publicación

 #define kMaxFieldHeight 9999 -(BOOL)sizeFontToFit:(NSString*)aString minSize:(float)aMinFontSize maxSize:(float)aMaxFontSize { float fudgeFactor = 16.0; float fontSize = aMaxFontSize; self.font = [self.font fontWithSize:fontSize]; CGSize tallerSize = CGSizeMake(self.frame.size.width-fudgeFactor,kMaxFieldHeight); CGSize stringSize = [aString sizeWithFont:self.font constrainedToSize:tallerSize lineBreakMode:UILineBreakModeWordWrap]; while (stringSize.height >= self.frame.size.height) { if (fontSize <= aMinFontSize) // it just won't fit return NO; fontSize -= 1.0; self.font = [self.font fontWithSize:fontSize]; tallerSize = CGSizeMake(self.frame.size.width-fudgeFactor,kMaxFieldHeight); stringSize = [aString sizeWithFont:self.font constrainedToSize:tallerSize lineBreakMode:UILineBreakModeWordWrap]; } return YES; } 

Un enfoque similar a la respuesta de Arie Litovsky pero sin subclasificar (o usar una categoría) y no usar contentSize que no devolvió la altura correcta del texto prestado para mí. Probado en iOS 7:

 while (((CGSize) [_textView sizeThatFits:_textView.frame.size]).height > _textView.frame.size.height) { _textView.font = [_textView.font fontWithSize:_textView.font.pointSize-1]; } 

El enfoque es seguir reduciendo el tamaño de la fuente hasta que el texto encaje dentro del marco de la vista de texto.

Si fuera a usar esto en producción, aún tendría que:

  • Maneje el caso donde incluso con el tamaño de letra más pequeño posible el texto todavía no cabe.
  • Utilice un enfoque similar para boost el tamaño de la fuente si también desea escalar el texto para que se ajuste al marco.

Prueba esto, es mucho más simple:

 while (self.contentSize.height > self.frame.size.height) { self.font = [self.font fontWithSize:self.font.pointSize -1]; } 

Aquí está mi código de muestra. Básicamente, verifico el tamaño esperado para saber si el tamaño de la fuente necesita boost o disminuir. Necesita agregar UITextViewDelegate a su clase para asegurarse de que funcione

 - (void)updateTextFont:(UITextView *)textView { // Only run if has text, otherwise it will make infinity loop if (textView.text.length == 0 || CGSizeEqualToSize(textView.bounds.size, CGSizeZero)) return; /* - Update textView font size If expectHeight > textViewHeight => descrease font size n point until it reach textViewHeight If expectHeight < textViewHeight => inscrease font size n point until it reach textViewHeight */ CGSize textViewSize = textView.frame.size; CGFloat fixedWidth = textViewSize.width; CGSize expectSize = [textView sizeThatFits:CGSizeMake(fixedWidth, MAXFLOAT)]; UIFont *expectFont = textView.font; if (expectSize.height > textViewSize.height) { while ([textView sizeThatFits:CGSizeMake(fixedWidth, MAXFLOAT)].height > textViewSize.height) { expectFont = [textView.font fontWithSize:(textView.font.pointSize-1)]; textView.font = expectFont; } } else { while ([textView sizeThatFits:CGSizeMake(fixedWidth, MAXFLOAT)].height < textViewSize.height) { expectFont = textView.font; textView.font = [textView.font fontWithSize:(textView.font.pointSize+1)]; } textView.font = expectFont; } } 

Esta propiedad solo está disponible en UITextFields. Para hacer esto en una UITextView, tendrías que mirar constantemente el texto y ajustar manualmente el tamaño de la fuente a medida que eso cambiaba.

para veloz 3

  func updateTextFont(textView : UITextView) { if (textView.text.isEmpty || textView.bounds.size.equalTo(CGSize.zero)) { return; } let textViewSize = textView.frame.size; let fixedWidth = textViewSize.width; let expectSize = textView.sizeThatFits(CGSize(width : fixedWidth, height : CGFloat(MAXFLOAT))); var expectFont = textView.font; if (expectSize.height > textViewSize.height) { while (textView.sizeThatFits(CGSize(width : fixedWidth, height : CGFloat(MAXFLOAT))).height > textViewSize.height) { expectFont = textView.font!.withSize(textView.font!.pointSize - 1) textView.font = expectFont } } else { while (textView.sizeThatFits(CGSize(width : fixedWidth,height : CGFloat(MAXFLOAT))).height < textViewSize.height) { expectFont = textView.font; textView.font = textView.font!.withSize(textView.font!.pointSize + 1) } textView.font = expectFont; } } 

He convertido la respuesta de dementiazz y Matt Frear a Swift 3:

 func updateTextFont() { if (textView.text.isEmpty || textView.bounds.size.equalTo(CGSize.zero)) { return } let textViewSize = textView.frame.size let fixedWidth = textViewSize.width let expectSize = textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat(MAXFLOAT))) var expectFont = textView.font if (expectSize.height > textViewSize.height) { while (textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat(MAXFLOAT))).height > textViewSize.height) { expectFont = textView.font!.withSize(textView.font!.pointSize - 1) textView.font = expectFont } } else { while (textView.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat(MAXFLOAT))).height < textViewSize.height) { expectFont = textView.font textView.font = textView.font!.withSize(textView.font!.pointSize + 1) } textView.font = expectFont } } 

He convertido la respuesta de Matt Frear a Swift 4.1 como extensión para UITextView:

 extension UITextView { func updateTextFont() { if (self.text.isEmpty || self.bounds.size.equalTo(CGSize.zero)) { return; } let textViewSize = self.frame.size; let fixedWidth = textViewSize.width; let expectSize = self.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat(MAXFLOAT))) var expectFont = self.font if (expectSize.height > textViewSize.height) { while (self.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat(MAXFLOAT))).height > textViewSize.height) { expectFont = self.font!.withSize(self.font!.pointSize - 1) self.font = expectFont } } else { while (self.sizeThatFits(CGSize(width: fixedWidth, height: CGFloat(MAXFLOAT))).height < textViewSize.height) { expectFont = self.font self.font = self.font!.withSize(self.font!.pointSize + 1) } self.font = expectFont } } 

}

Una versión actualizada del código de @Arie Litovsky. Esto funciona en iOS7 y versiones posteriores y extiende el tamaño de la fuente tanto hacia arriba como hacia abajo para que el texto encaje.

 - (void) stretchFontToFit:(UITextView*)textView { while( textView.contentSize.height < textView.frame.size.height ) { textView.font = [textView.font fontWithSize:textView.font.pointSize +1]; [textView layoutIfNeeded]; } while( textView.contentSize.height > textView.frame.size.height ) { textView.font = [textView.font fontWithSize:textView.font.pointSize -1]; [textView layoutIfNeeded]; } } 

En viewDidLoad:

 textView.textContainer.lineFragmentPadding = 0; textView.textContainerInset = UIEdgeInsetsMake(0, 0, 0, 0); 

Necesita agregar UITextViewDelegate:

 - (void)updateTextFont:(UITextView *)textView { CGSize textViewSize = textView.frame.size; CGSize sizeOfText = [textView.text sizeWithAttributes:@{NSFontAttributeName: textView.font}]; CGFloat fontOfWidth = floorf(textView.font.pointSize / sizeOfText.height * textViewSize.height); CGFloat fontOfHeight = floorf(textView.font.pointSize / sizeOfText.width * textViewSize.width); textView.font = [textView.font fontWithSize:MIN(fontOfHeight, fontOfWidth)]; } 

U puede hacerlo fácilmente mediante el uso de

  • self.textview.font =

self.textview.font = UIFont (name: self.textview.font! .fontName,
tamaño: self.textview.frame.size.height / 10)!

divide textview.frame.size.height sobre alguna constante en función de tus necesidades …

Aquí hay una solución para Swift 4 (basada en la respuesta de Arie Litovsky ), puedes poner este código en el método de delegado textViewDidChange(_ textView: UITextView) :

Escalando la fuente:

  while (textView.contentSize.height > textView.frame.size.height) { guard let fontName = textView.font?.fontName, let fontSize = textView.font?.pointSize else {return} if fontSize < 12 { return } textView.font = UIFont(name: fontName, size: fontSize - 1) textView.layoutIfNeeded() } 

Y escalando la fuente:

  while (textView.contentSize.height < textView.frame.size.height) { guard let fontName = textView.font?.fontName, let fontSize = textView.font?.pointSize else {return} if fontSize > 15 { return } textView.font = UIFont(name: fontName, size: fontSize + 1) textView.layoutIfNeeded() } 

Puede cambiar fontSize < 12 y fontSize > 15 para que se ajuste a sus necesidades en tamaño mínimo y máximo de fuente.