Question

J'essaie de mesurer la taille visuelle d'un NSString qui prend en compte le nombre de lignes que je peux rendre. Cependant, sizeWithFont ne prend pas en compte la propriété numberOfLines? Donc, mon algorithme de mise en page positionne tout plus bas que nécessaire.

_price = [[UILabel alloc] init];
_price.text = myPriceValue;
_price.lineBreakMode = UILineBreakModeWordWrap;
_price.numberOfLines = 3;
_price.backgroundColor = [UIColor clearColor];
_price.textColor = TTSTYLEVAR(colorPrice);
/// the follow code ignores numberOfLines and just tells me the size of the whole block.  
// I'd like it to be aware of numberOfLines
//
CGSize priceSize = [_price.text sizeWithFont:_price.font
        constrainedToSize:CGSizeMake(maxWidth, CGFLOAT_MAX)
        lineBreakMode:UILineBreakModeWordWrap];

Quelqu'un sait-il comment faire cela à l'aide du kit de développement logiciel (SDK) de l'iPhone?

Était-ce utile?

La solution

Au lieu de CGFLOAT_MAX pour la hauteur maximale de votre calcul de texte, essayez d'obtenir la taille d'une ligne avec ceci:

[_price.text sizeWithFont:_price.font].height

puis multipliez ce nombre par le nombre maximal de lignes que vous souhaitez, puis insérez-le dans la hauteur de la taille à laquelle vous vous contraignez. Cela ressemblerait probablement à ceci:

_price = [[UILabel alloc] init];
_price.text = myPriceValue;
_price.lineBreakMode = UILineBreakModeWordWrap;
_price.numberOfLines = 3;
_price.backgroundColor = [UIColor clearColor];
_price.textColor = TTSTYLEVAR(colorPrice);
CGFloat lineHeight = [_price.text sizeWithFont:_price.font].height;
CGSize priceSize = [_price.text sizeWithFont:_price.font
        constrainedToSize:CGSizeMake(maxWidth, lineHeight * _price.numberOfLines)
        lineBreakMode:UILineBreakModeWordWrap];

Ne l'utilisez pas si vous définissez un nombre de lignes égal à 0 car votre hauteur maximale sera 0 dans ce cas; vous devriez alors utiliser CGFLOAT_MAX.

Autres conseils

Utilisez le paramètre sizeToFit de UILabel au lieu de sizeWithFont: pour mettre en forme un UILabel multiligne, car sizeWithFont: tronquera la chaîne (voir la documentation Apple). Le code suivant réduit la taille de la police d'une étiquette jusqu'à ce que le texte corresponde à la taille spécifiée ... plusieurs lignes de texte seront utilisées dès qu'elles s'intègrent à la hauteur spécifiée:

-(void)setFontSizeOfMultiLineLabel: (UILabel*)label 
        toFitSize: (CGSize) size 
        forMaxFontSize: (CGFloat) maxFontSize 
        andMinFontSize: (CGFloat) minFontSize 
        startCharacterWrapAtSize: (CGFloat)characterWrapSize{

CGRect constraintSize = CGRectMake(0, 0, size.width, 0);
label.frame = constraintSize;
label.lineBreakMode = UILineBreakModeWordWrap;
label.numberOfLines = 0; // allow any number of lines

for (int i = maxFontSize; i > minFontSize; i--) {

    if((i < characterWrapSize) && (label.lineBreakMode == UILineBreakModeWordWrap)){
        // start over again with lineBreakeMode set to character wrap 
        i = maxFontSize;
        label.lineBreakMode = UILineBreakModeCharacterWrap;
    }

    label.font = [label.font fontWithSize:i];
    [label sizeToFit];
    if(label.frame.size.height < size.height){
        break;
    }       
    label.frame = constraintSize;
  } 
}

Appelez cette opération avec une étiquette comportant votre texte et votre police préférés:

UILabel *label = [[UILabel alloc] initWithFrame: CGRectZero];   
label.backgroundColor = [UIColor clearColor];   
label.textColor = [UIColor whiteColor];
label.text = text;
label.font = [UIFont fontWithName: @"Helvetica" size: 16];
[self setFontSizeOfMultiLineLabel: label toFitSize: CGSizeMake(200, 44) forMaxFontSize: 16 andMinFontSize: 8 startCharacterWrapAtSize: 11]; 

Le paramètre startCharacterWrapAtSize vous permet de choisir d'utiliser characterWrap à partir de la taille de la police. Cela devrait économiser de l'espace dans le cas où wordWrap utiliserait des polices vraiment petites.

edit: correction de bug

Au lieu d'essayer de le faire en un seul appel, procédez comme suit (excusez le pseudocode, il est tardif):

NSString *s = _price.text;
UIFont *font = _price.font;
CGFloat fontSize = font.pointSize;

while (TRUE)
{
   CGSize priceSize = [s sizeWithFont: font constrainedToSize: 
       CGSizeMake(maxWidth, fontSize) lineBreakMode: UILineBreakModeWordWrap];

    if ( /* priceSize is satisfactory */ )
    {
        break; // Make sure this exits, eventually!!!
    }
    fontSize -= 1.0; // or a smaller decrement if you like
    font = // new, smaller font

}

La bonne réponse est, bien sûr, vous devez définir numberOfLines sur 0, ce qui obligera la structure à calculer le résultat avec le nombre de lignes dont il a besoin. Voir aussi cette question .

Bien sûr, cela n’en tient pas compte, car rien n’est appelé ou transmis ne contient cette information. Vous travaillez strictement avec des chaînes, des tailles et des polices. C'est l'étiquette qui contient le nombre de lignes.

Je ne sais pas quel est exactement votre problème. obtenez-vous une taille qui est trop grande ou trop courte, ou quoi? Vous pouvez connaître le nombre de lignes de texte en divisant la hauteur du résultat par la hauteur de la police, qui correspond à la valeur de l’ascendeur plus le descendant, je crois.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top