web-dev-qa-db-fra.com

Obtenir dynamiquement la hauteur de UILabel en fonction du texte renvoie une valeur différente pour iOS 7.0 et iOS 6.1

J'utilise cette méthode pour obtenir la hauteur de UILabel dynamiquement:

+(CGSize) GetSizeOfLabelForGivenText:(UILabel*)label Font:(UIFont*)fontForLabel Size:  (CGSize)LabelSize{
    label.numberOfLines = 0;
    CGSize labelSize = [label.text sizeWithFont:fontForLabel constrainedToSize:LabelSize lineBreakMode:NSLineBreakByCharWrapping];
    return (labelSize);
}

Avec cette solution, je reçois la taille exacte d’UILabel si mon code s’exécute sous iOS 8 Mais si j’exécute mon application sur iOS7, il renvoie une valeur différente.

23
Sumeet Mourya

Vous devez définir dynamiquement le cadre, comme ci-dessous:

//Compatible for both ios6 and ios7.  

CGSize constrainedSize = CGSizeMake(self.resizableLable.frame.size.width  , 9999);

NSDictionary *attributesDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
                                      [UIFont fontWithName:@"HelveticaNeue" size:11.0], NSFontAttributeName,
                                      nil];

NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:@"textToShow" attributes:attributesDictionary];

CGRect requiredHeight = [string boundingRectWithSize:constrainedSize options:NSStringDrawingUsesLineFragmentOrigin context:nil];

if (requiredHeight.size.width > self.resizableLable.frame.size.width) {
    requiredHeight = CGRectMake(0,0, self.resizableLable.frame.size.width, requiredHeight.size.height);
}
CGRect newFrame = self.resizableLable.frame;
newFrame.size.height = requiredHeight.size.height;
self.resizableLable.frame = newFrame;
26
preetam

Voici une solution totale pour la largeur et la hauteur. Mettez-les dans votre AppDelegate:

+(void)fixHeightOfThisLabel:(UILabel *)aLabel
{
    aLabel.frame = CGRectMake(aLabel.frame.Origin.x,
                              aLabel.frame.Origin.y,
                              aLabel.frame.size.width,
                              [AppDelegate heightOfTextForString:aLabel.text
                                                         andFont:aLabel.font
                                                         maxSize:CGSizeMake(aLabel.frame.size.width, MAXFLOAT)]);
}

+(CGFloat)heightOfTextForString:(NSString *)aString andFont:(UIFont *)aFont maxSize:(CGSize)aSize
{
    // iOS7
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0)
    {
        CGSize sizeOfText = [aString boundingRectWithSize: aSize
                                                  options: (NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading)
                                               attributes: [NSDictionary dictionaryWithObject:aFont
                                                                                       forKey:NSFontAttributeName]
                                                  context: nil].size;

        return ceilf(sizeOfText.height);
    }

    // iOS6
    CGSize textSize = [aString sizeWithFont:aFont
                          constrainedToSize:aSize
                              lineBreakMode:NSLineBreakByWordWrapping];
    return ceilf(textSize.height;
}

+(void)fixWidthOfThisLabel:(UILabel *)aLabel
{
    aLabel.frame = CGRectMake(aLabel.frame.Origin.x,
                              aLabel.frame.Origin.y,
                                [AppDelegate widthOfTextForString:aLabel.text
                                                          andFont:aLabel.font
                                                          maxSize:CGSizeMake(MAXFLOAT, aLabel.frame.size.height)],
                              aLabel.frame.size.height);
}

+(CGFloat)widthOfTextForString:(NSString *)aString andFont:(UIFont *)aFont maxSize:(CGSize)aSize
{
    // iOS7
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0)
    {
        CGSize sizeOfText = [aString boundingRectWithSize: aSize
                                                  options: (NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading)
                                               attributes: [NSDictionary dictionaryWithObject:aFont
                                                                                       forKey:NSFontAttributeName]
                                                  context: nil].size;

        return ceilf(sizeOfText.width);
    }

    // iOS6
    CGSize textSize = [aString sizeWithFont:aFont
                          constrainedToSize:aSize
                              lineBreakMode:NSLineBreakByWordWrapping];
    return ceilf(textSize.width);
}

puis pour utiliser ceci, définissez le texte de l'étiquette:

label.numberOfLines = 0;
label.text = @"Everyone loves Stack OverFlow";

et appelez:

[AppDelegate fixHeightOfThisLabel:label];

Remarque: le numéro de l'étiquette de l'étiquette doit être défini sur 0 .

5
Andrew Bennett

si vous utilisez l'une des polices système, celles-ci ont été modifiées dans iOS 7 et leur taille serait donc différente.


De plus, sizeWithFont:constrainedToSize:lineBreakMode: est obsolète dans iOS 7. Utilisez sizeWithAttributes: à la place (si vous êtes sur iOS 7).

4
liamnichols

La réponse acceptée ne me satisfaisait pas alors j'ai dû creuser cela dans mon code:

CGSize possibleSize = [string sizeWithFont:[UIFont fontWithName:@"HelveticaNeue" size:10] //font you are using
                          constrainedToSize:CGSizeMake(skillsMessage.frame.size.width,9999)
                              lineBreakMode:NSLineBreakByWordWrapping];


CGRect newFrame = label.frame;
newFrame.size.height = possibleSize.height;
label.frame = newFrame;
2
stackOverFlew

La réponse acceptée est trop longue. Vous pouvez utiliser les éléments suivants:

+(CGSize) GetSizeOfLabelForGivenText:(UILabel*)label Font:(UIFont*)fontForLabel Size:  (CGSize) constraintSize{
    label.numberOfLines = 0;
    CGRect labelRect = [label.text boundingRectWithSize:constraintSize options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading) attributes:@{NSFontAttributeName:fontForLabel} context:nil];
    return (labelRect.size);
}
1
Armin

J'ai tout le temps utiliser sizeThatFits:

CGRect frame = myLabel.frame;
CGSize constraint = CGSizeMake(CGRectGetWidth(myLabel.frame), 20000.0f);
CGSize size = [myLabel sizeThatFits:constraint];
frame.size.height = size.height;
myLabel.frame = frame;

Tu peux essayer ça

1
Js Lim

Quelle que soit la hauteur que j'obtienne via ce code (méthode que j'ai écrite dans cette question ci-dessus). Il fournit la hauteur en float value (86.4) nous devons obtenir la valeur de la hauteur avec ceil (87)_ _ au lieu de la valeur telle qu'elle est (86.4)_. J'ai résolu mon problème avec cette approche. Et merci pour vos réponses.

0
Sumeet Mourya

Cette méthode est utilisée et testée par moi d'iOS 7 à iOS 11.4

+ (CGFloat)getLabelHeight:(UILabel*)label
{
    NSParameterAssert(label);
    CGSize limitLabel = CGSizeMake(label.frame.size.width, CGFLOAT_MAX);
    CGSize size;

    NSStringDrawingContext *context = [[NSStringDrawingContext alloc] init];
    CGSize labelBox = [label.text boundingRectWithSize: limitLabel
                                                  options: NSStringDrawingUsesLineFragmentOrigin
                                               attributes: @{ NSFontAttributeName:label.font }
                                                  context: context].size;

    size = CGSizeMake(ceil(labelBox.width), ceil(labelBox.height));
    return size.height;
}

Donc, vous pouvez utiliser comme ceci:

CGFloat sizeOfFontTest = 12.0;
    UILabel *testLabel = [[UILabel alloc] initWithFrame: CGRectMake(0, 0, 100, 0)];
    [testLabel setFont: [UIFont systemFontOfSize: sizeOfFontTest]];
    [testLabel setText: @"Hello Stackoverflow Large String Example"];

    CGFloat heightTestLabel = [self getLabelHeight: testLabel];

    [testLabel setFrame: CGRectMake(testLabel.frame.Origin.x, testLabel.frame.Origin.y, testLabel.frame.size.width, heightAddrsLab)];
    [testLabel setNumberOfLines: sizeOfFontTest / heightTestLabel];
0
Ladd.c

Super simple. Obtenez simplement la zone du texte, divisez par la largeur, puis arrondissez à la hauteur la plus proche qui convient à votre police.

+ (CGFloat)heightForText:(NSString*)text font:(UIFont*)font withinWidth:(CGFloat)width {
    CGSize size = [text sizeWithAttributes:@{NSFontAttributeName:font}];
    CGFloat area = size.height * size.width;
    CGFloat height = roundf(area / width);
    return ceilf(height / font.lineHeight) * font.lineHeight;
}

Très bien une solution plug and play. Je l'utilise souvent dans une classe d'assistance, en particulier pour les UITableViewCells de taille dynamique.

J'espère que cela aidera les autres à l'avenir!

0
AlexKoren

C’est ce que j’ai finalement évoqué et j’espère que cela vous aidera. J'ai vérifié la version iOS comme le faisait Apple lui-même dans le Guide de la transition de l'interface utilisateur iOS 7 , qui implique de vérifier la version de Foundation Framework et utilisé #pragma pour supprimer le message d'erreur Obsolète: Avertissement avec iOS 7 ou version ultérieure avec "- (CGSize) sizeWithFont : (UIFont *) font constrainedToSize: taille (CGSize) ".

+ (CGSize)getStringBoundingSize:(NSString*)string forWidth:(CGFloat)width withFont:(UIFont*)font{

    CGSize maxSize = CGSizeMake(width, CGFLOAT_MAX);
    if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1) {
        // for iOS 6.1 or earlier
        // temporarily suppress the warning and then turn it back on
        // since sizeWithFont:constrainedToSize: deprecated on iOS 7 or later
        #pragma clang diagnostic Push
        #pragma clang diagnostic ignored "-Wdeprecated-declarations"
            maxSize = [string sizeWithFont:font constrainedToSize:maxSize];
        #pragma clang diagnostic pop

    } else {
        // for iOS 7 or later
        maxSize = [string sizeWithAttributes:@{NSFontAttributeName:font}];

    }
    return maxSize;
}
0

J'ai une situation où j'ai besoin de définir la hauteur de l'étiquette dynamiquement en fonction du texte. J'utilise Xcode 7.1 et la cible de déploiement de mon projet est 7.0, mais je l'ai testé sur un simulateur iOS 9 et la solution suivante fonctionne pour moi. Voici la solution: Tout d’abord, vous allez créer un dictionnaire comme celui-ci:

NSDictionary *attributes = @{NSFontAttributeName:self.YOUR_LABEL.font};

maintenant, nous allons calculer la hauteur et la largeur de notre texte et transmettre le dictionnaire nouvellement créé.

    CGRect rect = [YOUR_TEXT_STRING boundingRectWithSize:CGSizeMake(LABEL_WIDTH, CGFLOAT_MAX)
                                          options:NSStringDrawingUsesLineFragmentOrigin
                                       attributes:attributes
                                          context:nil];

Ensuite, nous allons définir le cadre de notre LABEL:

    self.YOUR_LABEL.frame = CGRectMake(self.YOUR_LABEL.frame.Origin.x, self.YOUR_LABEL.frame.Origin.y, self.YOUR_LABEL.frame.size.width, rect.size.height);

C'EST IS COMMENT J'AI ÉTABLI AVEC SUCCÈS LE CADRE DE MON ÉTIQUETTE SELON LE TEXTE.

0
Zulqarnain

La méthode sizeWithFont:constrainedToSize:lineBreakMode: est obsolète dans iOS7. Vous devriez utiliser sizeWithAttributes: à la place.

Exemple:

NSDictionary *fontAttributes = @{NSFontAttributeName : [UIFont systemFontOfSize:15]};
CGSize textSize = [self.myLabel.text sizeWithAttributes:fontAttributes];
CGFloat textWidth = textSize.width;
CGFloat textHeight = textSize.height;
0
Groot