Calcul de la hauteur de texte multiligne pour UILabel / UITableViewCell: différents résultats lors du calcul vs dessin réel

Cette question générale a été posée à plusieurs resockets: comment rendre UITableViewCells avec une quantité variable de texte et donc une hauteur variable. La réponse canonique est la suivante: vous calculez la hauteur dans le délégué de contrôleur de vue de table dans heightForRowAtIndexPath à l’aide de sizeWithFont: constrainedToSize: lineBreakMode :. Plus tard, la cellule est dessinée et vous utilisez quelque chose comme [label sizeToFit] si nécessaire, et tout fonctionne comme par magie.

Mon problème: je fais de l’encapsulation pour certaines cellules, car sizeWithFont: renvoie différentes dimensions du dessin réel.

Un exemple spécifique:

Le texte est le suivant: “Les gens oublient que @BillGates avait une ardoise sexy de 1/4 pouce d’épaisseur en 1993 de NEC. Quoi qu’il arrive cette semaine, ce ne sera pas du matériel!”

CGSize theSize = [text sizeWithFont:[UIFont systemFontOfSize:17.0f] constrainedToSize:CGSizeMake(310.0f, FLT_MAX) lineBreakMode:UILineBreakModeWordWrap]; NSLog(@"calculated size for %@: %f, %f",text, theSize.width, theSize.height); 

Cela renvoie: 306.000000, 84.000000. (Ie 4 lignes avec 17px et 4px, 21px).

Cependant, plus tard, lors du dessin de la cellule:

 label = (UILabel *)[cell viewWithTag:3]; label.text = [NSSsortingng ssortingngWithFormat:@"%@", text]; label.lineBreakMode = UILineBreakModeWordWrap; label.font = [UIFont systemFontOfSize:17.0f]; CGSize labelSize; labelSize = label.frame.size; NSLog(@"label size before resizing: %f, %f", labelSize.width, labelSize.height); [label sizeToFit]; labelSize = label.frame.size; NSLog(@"label size after resizing: %f, %f for text %@", labelSize.width, labelSize.height,text); 

(UILabel est chargé dans le cadre de UITableViewCell de NIB. Dans IB, il est défini sur 310px.)

Cela devrait retourner exactement la même taille que ci-dessus. Au lieu de cela, j’obtiens 281.000000, 105.000000 comme dimensions après l’appel sizeToFit. Il y a maintenant 5 lignes au moment du dessin au lieu de 4, et le texte déborde, je vois le débordement dans l’interface utilisateur.

Donc, pour le même texte, je calcule deux dimensions différentes et je n’arrive pas à le comprendre. Est-ce quelque chose à propos de UILabel? At-il des marges intérieures? Cela continue à se produire pour certains textes, mais pas pour d’autres, et je n’ai pas trouvé quelque chose de particulier à propos des cordes; semble aléatoire. Cette rubrique met en évidence qu’il existe deux passages de traitement: calcul de la hauteur par rapport au dessin réel. Ceci est cohérent avec ce que je vois. Mais je ne comprends pas exactement ce qui se passe ou comment le réparer.

La question: pourquoi vois-je deux tailles différentes et comment puis-je le réparer?

Bien sûr, la solution est évidente 30 secondes après la publication. Peut-être utile aux autres aussi …

La taille par sizeWithFont: était correcte. Les tailles que j’ai calculées de la manière ci-dessus étaient incorrectes, car [label sizeToFit] réduit la largeur du cadre de l’étiquette. Lors d’appels ultérieurs au même code, il a commencé avec la trame qui avait peut-être déjà été réduite.

La solution consistait simplement à redéfinir la width du cadre sur une bonne largeur connue avant de procéder au dimensionnement:

 CGRect labelFrame = label.frame; labelFrame.size.width = 310; label.frame = labelFrame; [label sizeToFit]; 

Pour les étiquettes multilignes, vous devez définir

 cell.textLabel.numberOfLines = 0; 

et alors

 [cell.textLabel sizeToFit]; 

Mais pour une belle vue, vous devez append des pixels de remplissage. Et votre application sera géniale!

  titleSize = [title sizeWithFont:[UIFont systemFontOfSize:(CGFloat)17.0] constrainedToSize:CGSizeMake(280, 2000) lineBreakMode:NSLineBreakByWordWrapping];