2010-01-10 2 views

Répondre

2

Cette propriété est uniquement disponible sur UITextFields. Pour faire cela dans un UITextView, vous devez constamment regarder le texte et ajuster manuellement la taille de la police comme cela a changé.

+0

Ah, y at-il un exemple de code là-bas qui fait cela? J'ai regardé autour de moi et n'ai rien trouvé. Merci beaucoup! –

+0

Je ne suis pas au courant d'un exemple de code; Je n'ai jamais entendu parler de quelqu'un qui essayait de le faire auparavant. –

8

Ceci, dans une catégorie sur UITextView, devrait faire l'affaire. Pourquoi vous avez besoin du fudgefactor, voir 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

dans iOS> 7.0 vous devez changer UILineBreakModeWordWrap à NSLineBreakByWordWrapping – ignotusverum

+0

juste curieux, comment savez-vous "fudgeFactor = 16.0"? Je crois que cette valeur devrait être plus petite quand la taille du texte est plus petite – Jacky

5

Essayez cela, il est beaucoup plus simple:

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

+1, cela fonctionne bien – NAZIK

+3

Ne fonctionne pas dans iOS7. –

+2

@BradMoore, vous devez ajouter une ligne supplémentaire: [textView layoutSubviews]; – Jacky

6

Une approche similaire à la réponse de Arie Litovsky mais sans sous-classage (ou l'utilisation d'une catégorie) et n'utilisant pas contentSize qui n'a pas retourné la bonne hauteur du texte rendu pour moi. Testée sur iOS 7:

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

L'approche est de continuer à réduire la taille de la police jusqu'à ce que le texte correspond juste à l'intérieur du cadre de la vue du texte.

Si vous allez utiliser dans la production que vous auriez encore besoin de:

  • gérer le cas où même avec la taille des caractères plus petit possible le texte encore ne tient pas.
  • Utilisez une approche similaire à augmenter la taille de la police si vous souhaitez également mettre à l'échelle le texte jusqu'à pour s'adapter au cadre.
+0

Une approche rapide pour gérer le cas de police «augmentation»: http://pastie.org/8975356 – Anil

2

Voici mon exemple de code. Fondamentalement, je vérifie la taille attendue pour savoir si la taille de la police doit augmenter ou diminuer. Vous devez ajouter UITextViewDelegate à votre classe pour faire fonctionnement sûr de

il
- (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

Je suis curieux de savoir ce que la clause else fait ici. Vous définissez un 'expectFont' à la police' textView'' avant de le modifier ... puis vous le réglez sur la 'font' non modifiée? Est-ce pour empêcher le saut de la taille du texte? –

+0

@StephenPaul dans la clause else, si while ne s'exécute pas, le 'textView.font' ne change pas (parce que' expectFont' est en fait original 'textView.font'). Mais si en cours d'exécution au moins 1 fois, 'expectFont' est changé et nous avons besoin de le mettre à jour après avoir terminé la boucle. Je pourrais faire un drapeau pour déterminer si couru ou pas, mais je n'ai pas fait. Au lieu de cela, je le groupe dans la dernière ligne 'textView.font = expectFont' – nahung89

+0

Si la boucle while s'exécute au moins 1 fois, vous stockez la police courante dans une variable 'expectFont'. Ensuite, vous augmentez la police de 'textView' d'un point, mais lorsque cette boucle existe, vous voyez que la police' textView' revient à ce qu'elle était ... –

10

J'ai converti dementiazz's answer à 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

Vous pouvez également ajouter la taille de police min et max pour éviter les tailles inattendues. (trop grand ou trop petit) Je viens d'ajouter la condition "&& (textView.font! .pointSize> CGFloat (minSize))" à votre temps – RubenVot

+0

@RubenVot, quand devrions-nous utiliser cette fonction? – Shyam

0

Une version mise à jour du code de @Arie Litovsky. Cela fonctionne dans iOS7 et versions ultérieures et étend la taille de la police à la fois vers le haut et vers le bas afin que le texte s'adapte.

- (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); 

Vous devez ajouter 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

J'ai converti la réponse de dementiazz & Matt Frear à 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

Fonctionne pour moi. Merci! –

-1

U pouvez facilement le faire en utilisant

  • self.textview.font =

self.textview.font = UIFont (nom: self.textview.font .fontName,
taille: self.textview.frame. size.height/10)!

fracture textview.frame.size.height sur une constante en fonction de vos besoins ..

1

pour 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

Voici une solution pour Swift 4 (basé sur Arie Litovsky réponse), vous pouvez mettre ce code dans textViewDidChange(_ textView: UITextView) méthode de délégué:

Réduire la police:

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() 
    } 

et l'élargissement de la police:

 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() 
    } 

Vous pouvez modifier le fontSize < 12 et fontSize > 15 pour répondre à vos besoins en taille de police minimum et maximum.

Questions connexes