2010-01-10 12 views

Respuesta

2

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.

+0

Ah, ¿hay algún código de muestra que haga esto? Miré a mi alrededor y no pude encontrar nada. ¡Muchas gracias! –

+0

No conozco ningún código de muestra; Nunca había escuchado que alguien intentara hacer esto antes. –

8

Esto, en una categoría en UITextView, debería hacer el truco. Por qué necesita el FudgeFactor, ver this post

#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; 
} 
+2

en iOS> 7.0 es necesario cambiar UILineBreakModeWordWrap a NSLineBreakByWordWrapping – ignotusverum

+0

con curiosidad, ¿cómo se sabe "fudgeFactor = 16.0"? Creo que este valor debería ser menor cuando el tamaño del texto es menor – Jacky

5

Prueba de esto, es mucho más simple:

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

+1, funciona bien – NAZIK

+3

No funciona en iOS7. –

+2

@BradMoore, necesita agregar una línea más: [textView layoutSubviews]; – Jacky

6

enfoque similar al de la respuesta de Arie Litovsky pero sin sub-classing (o el uso de una categoría) y no estoy usando 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 mantener la reducción del tamaño de la fuente hasta que el texto se ajusta exactamente dentro del marco de la vista de texto.

Si se va a usar esto en la producción a pesar de ello necesitará:

  • manejar el caso en que incluso con el tamaño más pequeño posible de la fuente del texto todavía no encaja.
  • Utilice un enfoque similar a aumente el tamaño de fuente si también desea escalar el texto hasta para que se ajuste al marco.
+0

Un enfoque rápido para manejar el caso de fuente "aumentar": http://pastie.org/8975356 – Anil

2

Aquí está mi código de muestra. Básicamente, verifico el tamaño esperado para saber si el tamaño de la fuente necesita aumentar o disminuir. Es necesario añadir UITextViewDelegate a su clase para asegurar que los trabajos de TI

- (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; 
    } 
} 
+0

Tengo curiosidad por saber qué hace la cláusula else aquí. Estableces un 'expectedFont' en la' fuente' 'textView'' antes de modificarlo ... luego lo configuras de nuevo en la' fuente' no modificada? ¿Eso es para evitar los saltos hacia arriba y hacia abajo del tamaño del texto? –

+0

@StephenPaul en la cláusula else, si while no se ejecuta, 'textView.font' no cambia (porque' expectFont' es en realidad 'textView.font' original). Pero si mientras se ejecuta al menos 1 vez, 'expectFont' se cambia y tenemos que actualizarlo después de terminar el ciclo. Podría hacer una bandera para determinar mientras corría o no, pero no lo hice. En cambio, lo agrupo en la última línea 'textView.font = expectFont' – nahung89

+0

si el ciclo while se ejecuta al menos 1 vez, usted almacena la fuente actual en una variable 'expectFont'. Luego aumentas la fuente 'textView' en un punto, pero luego cuando ese ciclo while sale, ves que la fuente' textView' vuelve a ser lo que era ... –

10

He convertido dementiazz's answer 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; 
    } 
} 
+0

También puede agregar el tamaño de fuente mínimo y máximo para evitar tamaños inesperados. (demasiado grande o demasiado pequeño) Acabo de agregar la condición "&& (textView.font! .pointSize> CGFloat (minSize))" a su tiempo – RubenVot

+0

@RubenVot, ¿cuándo deberíamos usar esta función? – Shyam

0

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]; 
    } 
} 
0

En viewDidLoad:

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

es necesario 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)]; 
} 
1

He convertido la respuesta de dementiazz & de 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 
    } 
} 
+0

Funciona para mí. ¡Gracias! –

-1

U poder fácil hacer esto mediante el uso de

  • self.textview.font =

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

división textview.frame.size.height a alguna constante en base a sus necesidades ..

1

para SWIFT 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; 
    } 
} 
-2

Aquí es una solución para Swift 4 (basado en Arie Litovsky respuesta), puede poner este código en textViewDidChange(_ textView: UITextView) delegar método:

Escalar 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 la ampliación de 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 el fontSize < 12 y fontSize > 15 para satisfacer sus necesidades de tamaño mínimo y máximo de la fuente.

Cuestiones relacionadas