Ajuster la hauteur UILabel en fonction du text

Considérons que j'ai le text suivant dans un UILabel (une longue ligne de text dynamic):

Comme l'armée des extraterrestres dépasse largement l'équipe, les joueurs doivent utiliser le monde post-apocalyptique à leur avantage, comme chercher une couverture derrière des bennes à ordures, des piliers, des voitures, des gravats et d'autres objects.

Je veux resize la hauteur UILabel's pour que le text puisse rentrer. J'utilise les propriétés suivantes de UILabel pour rendre le text à l'intérieur.

 myUILabel.lineBreakMode = UILineBreakModeWordWrap; myUILabel.numberOfLines = 0; 

S'il vous plaît laissez-moi savoir si je ne suis pas dans la bonne direction. Merci.

    sizeWithFont constrainedToSize:lineBreakMode: est la méthode à utiliser. Un exemple de comment l'utiliser est ci-dessous:

     //Calculate the expected size based on the font and linebreak mode of your label // FLT_MAX here simply means no constraint in height CGSize maximumLabelSize = CGSizeMake(296, FLT_MAX); CGSize expectedLabelSize = [yourSsortingng sizeWithFont:yourLabel.font constrainedToSize:maximumLabelSize lineBreakMode:yourLabel.lineBreakMode]; //adjust the label the the new height. CGRect newFrame = yourLabel.frame; newFrame.size.height = expectedLabelSize.height; yourLabel.frame = newFrame; 

    Vous alliez dans la bonne direction. Tout ce que vous devez faire est:

     myUILabel.numberOfLines = 0; myUILabel.text = @"Enter large amount of text here"; [myUILabel sizeToFit]; 

    Dans iOS 6, Apple a ajouté une propriété à UILabel qui simplifie grandement le redimensionnement dynamic dynamic des labels: preferredMaxLayoutWidth .

    L'utilisation de cette propriété en combinaison avec lineBreakMode = NSLineBreakByWordWrapping et la méthode sizeToFit permet de resize facilement une instance UILabel à la hauteur qui correspond au text entier.

    Une citation de la documentation iOS:

    preferredMaxLayoutWidth Largeur maximale préférée (en points) pour une label multiligne.

    Discussion Cette propriété affecte la taille de l'label lorsque des contraintes de disposition sont appliquées à celle-ci. Pendant la layout, si le text dépasse la largeur spécifiée par cette propriété, le text supplémentaire est envoyé à une ou plusieurs nouvelles lignes, ce qui augmente la hauteur de l'label.

    Un échantillon:

     ... UILabel *status = [[UILabel alloc] init]; status.lineBreakMode = NSLineBreakByWordWrapping; status.numberOfLines = 5; // limits to 5 lines; use 0 for unlimited. [self addSubview:status]; // self here is the parent view status.preferredMaxLayoutWidth = self.frame.size.width; // assumes the parent view has its frame already set. status.text = @"Some quite lengthy message may go here…"; [status sizeToFit]; [status setNeedsDisplay]; ... 

    Au lieu de le faire par programmation, vous pouvez le faire dans Storyboard / XIB lors de la design.

    • Définissez la propriété Nombre de lignes de UIlabel sur 0 dans l'inspecteur d'attributes.
    • Définissez ensuite la contrainte de largeur / (ou) la contrainte de début et de fin conformément à l'exigence.
    • Ensuite, définissez la contrainte de hauteur avec la valeur minimale . Enfin, select la contrainte de hauteur que vous avez ajoutée et dans l'inspecteur de taille celui qui est en regard de l'inspecteur d'atsortingbut, modifiez la relation de la contrainte de hauteur d' égal àsupérieur à .

    Vérifiez ce travail parfaitement sans append une seule ligne de code. (Utilisation de Autolayout)

    J'ai fait une démo pour vous selon vos besoins. Téléchargez-le depuis le lien ci-dessous,

    Autoresize UIView et UILabel

    Guide étape par étape: –

    Étape 1: – Définir la contrainte sur UIView

    1) Leading 2) Top 3) Trailing (de la vue principale)

    entrez la description de l'image ici

    Étape 2: – Définir la contrainte sur l'label 1

    1) Conduire 2) Top 3) Trailing (De sa superview)

    entrez la description de l'image ici

    Étape 3: – Définir la contrainte sur Label 2

    1) Conduire 2) Trailing (De sa superview)

    entrez la description de l'image ici

    Étape 4: – Les plus rusés donnent botton à UILabel de UIView.

    entrez la description de l'image ici

    Étape 5: – (Facultatif) Définir contrainte à UIButton

    1) Menant 2) Bas 3) Trailing 4) Hauteur fixe (De la vue principale)

    entrez la description de l'image ici

    Sortie: –

    entrez la description de l'image ici

    Remarque: – Vérifiez que vous avez défini Number of lines = 0 dans la propriété Label.

    entrez la description de l'image ici

    J'espère que cette information suffira pour comprendre Autoresize UIView en fonction de la hauteur de UILabel et Autoresize UILabel Selon le text.

    Merci les gars de l'aide, voici le code que j'ai essayé qui fonctionne pour moi

      UILabel *instructions = [[UILabel alloc]initWithFrame:CGRectMake(10, 225, 300, 180)]; NSSsortingng *text = @"First take clear picture and then try to zoom in to fit the "; instructions.text = text; instructions.textAlignment = UITextAlignmentCenter; instructions.lineBreakMode = NSLineBreakByWordWrapping; [instructions setTextColor:[UIColor grayColor]]; CGSize expectedLabelSize = [text sizeWithFont:instructions.font constrainedToSize:instructions.frame.size lineBreakMode:UILineBreakModeWordWrap]; CGRect newFrame = instructions.frame; newFrame.size.height = expectedLabelSize.height; instructions.frame = newFrame; instructions.numberOfLines = 0; [instructions sizeToFit]; [self addSubview:instructions]; 

    Solution à iOS7 avant et iOS7 ci-dessus

     // // UILabel+DynamicHeight.m // For StackOverFlow // // Created by Vijay on 24/02/14. // Copyright (c) 2014 http://Vijay-Apple-Dev.blogspot.com. All rights reserved. // #import <UIKit/UIKit.h> #define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending) #define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending) #define iOS7_0 @"7.0" @interface UILabel (DynamicHeight) /*====================================================================*/ /* Calculate the size,bounds,frame of the Multi line Label */ /*====================================================================*/ /** * Returns the size of the Label * * @param aLabel To be used to calculte the height * * @return size of the Label */ -(CGSize)sizeOfMultiLineLabel; @end // // UILabel+DynamicHeight.m // For StackOverFlow // // Created by Vijay on 24/02/14. // Copyright (c) 2014 http://Vijay-Apple-Dev.blogspot.com. All rights reserved. // #import "UILabel+DynamicHeight.h" @implementation UILabel (DynamicHeight) /*====================================================================*/ /* Calculate the size,bounds,frame of the Multi line Label */ /*====================================================================*/ /** * Returns the size of the Label * * @param aLabel To be used to calculte the height * * @return size of the Label */ -(CGSize)sizeOfMultiLineLabel{ NSAssert(self, @"UILabel was nil"); //Label text NSSsortingng *aLabelTextSsortingng = [self text]; //Label font UIFont *aLabelFont = [self font]; //Width of the Label CGFloat aLabelSizeWidth = self.frame.size.width; if (SYSTEM_VERSION_LESS_THAN(iOS7_0)) { //version < 7.0 return [aLabelTextSsortingng sizeWithFont:aLabelFont constrainedToSize:CGSizeMake(aLabelSizeWidth, MAXFLOAT) lineBreakMode:NSLineBreakByWordWrapping]; } else if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(iOS7_0)) { //version >= 7.0 //Return the calculated size of the Label return [aLabelTextSsortingng boundingRectWithSize:CGSizeMake(aLabelSizeWidth, MAXFLOAT) options:NSSsortingngDrawingUsesLineFragmentOrigin atsortingbutes:@{ NSFontAtsortingbuteName : aLabelFont } context:nil].size; } return [self bounds].size; } @end 

    Comme sizeWithFont est obsolète, j'utilise celui-ci à la place.

    celui-ci obtient des attributes spécifiques à l'label.

     -(CGFloat)heightForLabel:(UILabel *)label withText:(NSSsortingng *)text{ NSAtsortingbutedSsortingng *atsortingbutedText = [[NSAtsortingbutedSsortingng alloc] initWithSsortingng:text atsortingbutes:@{NSFontAtsortingbuteName:label.font}]; CGRect rect = [atsortingbutedText boundingRectWithSize:(CGSize){label.frame.size.width, CGFLOAT_MAX} options:NSSsortingngDrawingUsesLineFragmentOrigin context:nil]; return ceil(rect.size.height); } 

    Voici une version de catégorie:

    UILabel + AutoSize.h #import

     @interface UILabel (AutoSize) - (void) autosizeForWidth: (int) width; @end 

    UILabel + AutoSize.m

     #import "UILabel+AutoSize.h" @implementation UILabel (AutoSize) - (void) autosizeForWidth: (int) width { self.lineBreakMode = UILineBreakModeWordWrap; self.numberOfLines = 0; CGSize maximumLabelSize = CGSizeMake(width, FLT_MAX); CGSize expectedLabelSize = [self.text sizeWithFont:self.font constrainedToSize:maximumLabelSize lineBreakMode:self.lineBreakMode]; CGRect newFrame = self.frame; newFrame.size.height = expectedLabelSize.height; self.frame = newFrame; } @end 

    Vous pouvez implémenter TableViewController's (UITableViewCell *)tableView:cellForRowAtIndexPath de la façon suivante (par exemple):

     #define CELL_LABEL_TAG 1 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { NSSsortingng *text = @"my long text"; static NSSsortingng *MyIdentifier = @"MyIdentifier"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:identifier] autorelease]; } CGFloat width = [UIScreen mainScreen].bounds.size.width - 50; CGFloat height = [self textHeight:text] + 10; CGRect frame = CGRectMake(10.0f, 10.0f, width, height); UILabel *cellLabel = [[UILabel alloc] initWithFrame:frame]; cellLabel.tag = CELL_LABEL_TAG; cellLabel.textColor = [UIColor blackColor]; cellLabel.backgroundColor = [UIColor clearColor]; cellLabel.textAlignment = UITextAlignmentLeft; cellLabel.font = [UIFont systemFontOfSize:12.0f]; [cell.contentView addSubview:cellLabel]; [cellLabel release]; return cell; } UILabel *label = (UILabel *)[cell viewWithTag:CELL_LABEL_TAG]; label.text = text; label.numberOfLines = 0; [label sizeToFit]; return cell; 

    Utilisez également la sizeWithFont:constrainedToSize:lineBreakMode: pour calculer la hauteur du text.

    Le moyen le plus simple et le meilleur qui a fonctionné pour moi était d'appliquer une contrainte de hauteur à l'label et de définir la priorité sur faible , c'est-à-dire (250) dans le storyboard.

    Vous n'avez donc pas besoin de vous soucier de calculer la hauteur et la largeur par programmation, grâce au storyboard.

    Et pour ceux qui migrent vers iOS 8, voici une extension de class pour Swift:

     extension UILabel { func autoresize() { if let textNSSsortingng: NSSsortingng = self.text { let rect = textNSSsortingng.boundingRectWithSize(CGSizeMake(self.frame.size.width, CGFloat.max), options: NSSsortingngDrawingOptions.UsesLineFragmentOrigin, atsortingbutes: [NSFontAtsortingbuteName: self.font], context: nil) self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, rect.height) } } } 

    Méthode mise à jour

     + (CGFloat)heightForText:(NSSsortingng*)text font:(UIFont*)font withinWidth:(CGFloat)width { CGSize constraint = CGSizeMake(width, 20000.0f); CGSize size; CGSize boundingBox = [text boundingRectWithSize:constraint options:NSSsortingngDrawingUsesLineFragmentOrigin atsortingbutes:@{NSFontAtsortingbuteName:font} context:nil].size; size = CGSizeMake(ceil(boundingBox.width), ceil(boundingBox.height)); return size.height; } 

    Merci pour ce post. Cela m'a beaucoup aidé. Dans mon cas, je suis également en train d'éditer le text dans un controller séparé. J'ai remarqué que quand j'utilise:

     [cell.contentView addSubview:cellLabel]; 

    dans la tableView: cellForRowAtIndexPath: méthode que la vue d'label était continuellement rendue au-dessus de la vue précédente chaque fois que j'ai édité la cellule. Le text est devenu pixélisé, et quand quelque chose a été supprimé ou changé, la version précédente était visible sous la nouvelle version. Voici comment j'ai résolu le problème:

     if ([[cell.contentView subviews] count] > 0) { UIView *test = [[cell.contentView subviews] objectAtIndex:0]; [test removeFromSuperview]; } [cell.contentView insertSubview:cellLabel atIndex:0]; 

    Plus de superposition bizarre. S'il y a une meilleure façon de gérer cela, s'il vous plaît faites le moi savoir.

     UILabel *itemTitle = [[UILabel alloc] initWithFrame:CGRectMake(10.0f, 10,100, 200.0f)]; itemTitle.text = @"aseruy56uiytitfesh"; itemTitle.adjustsFontSizeToFitWidth = NO; itemTitle.autoresizingMask = UIViewAutoresizingFlexibleWidth; itemTitle.font = [UIFont boldSystemFontOfSize:18.0]; itemTitle.textColor = [UIColor blackColor]; itemTitle.shadowColor = [UIColor whiteColor]; itemTitle.shadowOffset = CGSizeMake(0, 1); itemTitle.backgroundColor = [UIColor blueColor]; itemTitle.lineBreakMode = UILineBreakModeWordWrap; itemTitle.numberOfLines = 0; [itemTitle sizeToFit]; [self.view addSubview:itemTitle]; 

    utilisez ceci ici toutes les propriétés sont utilisées sur l'label et testez-la en augmentant le text dans itemTitle.text

     itemTitle.text = @"diofgorigjveghnhkvjteinughntivugenvitugnvkejrfgnvkhv"; 

    il montrera la réponse parfaite comme vous avez besoin

    Vous pouvez l'utiliser comme une méthode, aussi bien. @Pyjamasam est très vrai, donc je fais juste sa méthode. Cela peut être utile pour quelqu'un d'autre

     -(CGRect)setDynamicHeightForLabel:(UILabel*)_lbl andMaxWidth:(float)_width{ CGSize maximumLabelSize = CGSizeMake(_width, FLT_MAX); CGSize expectedLabelSize = [_lbl.text sizeWithFont:_lbl.font constrainedToSize:maximumLabelSize lineBreakMode:_lbl.lineBreakMode]; //adjust the label the the new height. CGRect newFrame = _lbl.frame; newFrame.size.height = expectedLabelSize.height; return newFrame; } 

    et juste le définir comme ça

     label.frame = [self setDynamicHeightForLabel:label andMaxWidth:300.0]; 

    Swift 2:

      yourLabel.text = "your very long text" yourLabel.numberOfLines = 0 yourLabel.lineBreakMode = NSLineBreakMode.ByWordWrapping yourLabel.frame.size.width = 200 yourLabel.frame.size.height = CGFloat(MAXFLOAT) yourLabel.sizeToFit() 

    Les lignes intéressantes sont sizeToFit() en conjonction avec la définition d'un frame.size.height au flottant max, cela donnera de la place pour du text long, mais sizeToFit() le forcera à utiliser seulement le nécessaire, mais l'appellera TOUJOURS après avoir réglé le .frame.size.height .

    Je recommand de définir un .backgroundColor à des fins de debugging, de cette façon, vous pouvez voir le cadre en cours de rendu pour chaque cas.

    Pour faire cela dans Swift3, suivre le code:

      let labelSizeWithFixedWith = CGSize(width: 300, height: CGFloat.greatestFiniteMagnitude) let exactLabelsize = self.label.sizeThatFits(labelSizeWithFixedWith) self.label.frame = CGRect(origin: CGPoint(x: 20, y: 20), size: exactLabelsize) 

    Ceci est une ligne de code pour get la hauteur UILabel en utilisant Objective-c:

     labelObj.numberOfLines = 0; CGSize neededSize = [labelObj sizeThatFits:CGSizeMake(screenWidth, CGFLOAT_MAX)]; 

    et en utilisant. hauteur, vous obtiendrez la hauteur de l'label comme suit:

     neededSize.height 

    Une ligne est la réponse de Chris est faux.

     newFrame.size.height = maximumLabelSize.height; 

    devrait être

     newFrame.size.height = expectedLabelSize.height; 

    À part ça, c'est la bonne solution.

    Finalement, cela a fonctionné. Merci les gars.

    Je heightForRowAtIndexPath pas à travailler parce que j'essayais de resize l'label dans la méthode heightForRowAtIndexPath :

     - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 

    et (ouais idiot moi), je redimensionnais l'label par défaut dans la méthode cellForRowAtIndexPath – je cellForRowAtIndexPath sur le code que j'avais écrit précédemment:

     - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
     -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { cellIdentifier = @"myCell"; cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; cell.myUILabel.lineBreakMode = UILineBreakModeWordWrap; cell.myUILabel.numberOfLines = 0; cell.myUILabel.text = @"Some very very very very long text....." [cell.myUILabel.criterionDescriptionLabel sizeToFit]; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath]; CGFloat rowHeight = cell.myUILabel.frame.size.height + 10; return rowHeight; } 
     NSSsortingng *str = @"Please enter your text......"; CGSize lblSize = [str sizeWithFont:[UIFont systemFontOfSize:15] constrainedToSize: CGSizeMake(200.0f, 600.0f) lineBreakMode: NSLineBreakByWordWrapping]; UILabel *label = [[UILabel alloc]init]; label.frame = CGRectMake(60, 20, 200, lblSize.height); label.numberOfLines = 0; label.lineBreakMode = NSLineBreakByWordWrapping; label.font = [UIFont systemFontOfSize:15]; label.text = str; label.backgroundColor = [UIColor clearColor]; [label sizeToFit]; [self.view addSubview:label]; 

    Mon code:

     UILabel *label = [[UILabel alloc] init]; label.numberOfLines = 0; label.lineBreakMode = NSLineBreakByWordWrapping; label.text = text; label.textAlignment = NSTextAlignmentCenter; label.font = [UIFont fontWithName:_bodyTextFontFamily size:_bodyFontSize]; CGSize size = [label sizeThatFits:CGSizeMake(width, MAXFLOAT)]; float height = size.height; label.frame = CGRectMake(x, y, width, height); 

    Cette méthode donnera une hauteur parfaite

     -(float) getHeightForText:(NSSsortingng*) text withFont:(UIFont*) font andWidth:(float) width{ CGSize constraint = CGSizeMake(width , 20000.0f); CGSize title_size; float totalHeight; title_size = [text boundingRectWithSize:constraint options:NSSsortingngDrawingUsesLineFragmentOrigin atsortingbutes:@{ NSFontAtsortingbuteName : font } context:nil].size; totalHeight = ceil(title_size.height); CGFloat height = MAX(totalHeight, 40.0f); return height; } 
     myLabel.text = "your very long text" myLabel.numberOfLines = 0 myLabel.lineBreakMode = NSLineBreakMode.ByWordWrapping 

    Veuillez définir les contraintes pour UILable dans le storyboard, y compris en haut à gauche en bas à droite

    Mon approche pour calculer la hauteur dynamic de UILabel.

      let width = ... //< width of this label let text = ... //< display content label.numberOfLines = 0 label.lineBreakMode = .byWordWrapping label.preferredMaxLayoutWidth = width // Font of this label. //label.font = UIFont.systemFont(ofSize: 17.0) // Compute insortingnsicContentSize based on font, and preferredMaxLayoutWidth label.invalidateInsortingnsicContentSize() // Destination height let height = label.insortingnsicContentSize.height 

    Envelopper pour fonctionner:

     func computeHeight(text: Ssortingng, width: CGFloat) -> CGFloat { // A dummy label in order to compute dynamic height. let label = UILabel() label.numberOfLines = 0 label.lineBreakMode = .byWordWrapping label.font = UIFont.systemFont(ofSize: 17.0) label.preferredMaxLayoutWidth = width label.text = text label.invalidateInsortingnsicContentSize() let height = label.insortingnsicContentSize.height return height } 

    Lorsque la fonction autoLayout est activée, le redimensionnement ne fonctionne pas 🙂

    Le problème est qu'aucune des fonctions mentionnées n'est réalisable et pour certaines strings, la police returnnera une valeur de hauteur incorrecte. Surtout échouera pour les texts atsortingbués.

    La seule solution réalist est ici: https://stackoverflow.com/a/4214978/699944 et le point est d'utiliser CoreText pour calculer manuellement la hauteur de chaque ligne pour get la bonne taille. Il n'y a pas d'autre moyen connu de le faire.

    Cette méthode fonctionnera pour iOS 6 et 7

     - (float)heightForLabelSize:(CGSize)maximumLabelSize Font:(UIFont *)font Ssortingng:(NSSsortingng*)ssortingng { if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) { NSDictionary *ssortingngAtsortingbutes = [NSDictionary dictionaryWithObject:font forKey: NSFontAtsortingbuteName]; CGSize adjustedLabelSize = [ssortingng maximumLabelSize options:NSSsortingngDrawingTruncatesLastVisibleLine|NSSsortingngDrawingUsesLineFragmentOrigin atsortingbutes:ssortingngAtsortingbutes context:nil].size; return adjustedLabelSize.height; } else { CGSize adjustedLabelSize = [ssortingng sizeWithFont:font constrainedToSize:maximumLabelSize lineBreakMode:NSLineBreakByWordWrapping]; return adjustedLabelSize.height; } }