web-dev-qa-db-fra.com

Modifier la hauteur UITableViewCell en fonction de la quantité de texte

Je dois pouvoir ajuster la hauteur d'une cellule unique dans mon UITableView afin qu'elle corresponde à la quantité de texte dans son étiquette de détail.

J'ai joué avec ce qui suit mais ça ne marche pas pour moi:

Comment insérer du texte dans un UITableViewCell sans cellule personnalisée

J'espère que vous pourrez aider, merci.

MODIFIER:

Code tenté:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
    cell.textLabel.numberOfLines = 0;
    cell.textLabel.font = [UIFont fontWithName:@"Helvetica" size:17.0];
}

et

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *cellText = @"Go get some text for your cell.";
    UIFont *cellFont = [UIFont fontWithName:@"Helvetica" size:17.0];
    CGSize constraintSize = CGSizeMake(280.0f, MAXFLOAT);
    CGSize labelSize = [cellText sizeWithFont:cellFont constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];

    return labelSize.height + 20;
}

Cela n'a pas fonctionné, il affiche la chaîne entière sur la cellule, mais la hauteur de la cellule n'est pas du tout affectée.

54
Josh Kahane

En fonction du code que vous avez fourni, je pense que vous augmentez uniquement la hauteur de la cellule et non la hauteur de cell.textLabel.

Idéalement, vous devez définir la taille de trame de cell.textLabel et la cellule pour que vous puissiez voir le texte intégral dans la cellule.

Une bonne façon de voir ce qui ne va pas avec une vue en termes de taille est de la colorer différemment de l'arrière-plan (essayez de définir le fond cell.textLabel sur jaune) et de voir si la hauteur est réellement définie.

Voici comment cela devrait être

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    cell.textLabel.lineBreakMode = NSLineBreakByWordWrapping;
    cell.textLabel.numberOfLines = 0;
    cell.textLabel.font = [UIFont fontWithName:@"Helvetica" size:17.0];

    NSString *cellText = @"Go get some text for your cell.";
    UIFont *cellFont = cell.textLabel.font;
    CGSize constraintSize = CGSizeMake(280.0f, MAXFLOAT);
    CGSize labelSize = [cellText sizeWithFont:cellFont constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];
    cell.textlabel.frame.size = labelSize; 
    cell.text = cellText;
}

J'espère que cela t'aides!

update: Ceci est une réponse assez ancienne et de nombreuses lignes de cette réponse peuvent être obsolètes.

20
Nitin Alabur

C'est simple, ajoutez ceci à votre code:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return UITableViewAutomaticDimension;
}

Il compte automatiquement une hauteur de ligne et retourne un float ... :-)

J'espère que cela t'aides!

80
stepik21

Bonjour Josh,

À l'aide de tableView:heightForRowAtIndexPath:, vous pouvez indiquer la taille de chaque ligne au moment de l'exécution. maintenant votre problème est de savoir comment obtenir la hauteur de votre chaîne il y a une fonction dans la classe NSString par ce code votre problème,

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
  NSString *str = [dataSourceArray objectAtIndex:indexPath.row];
    CGSize size = [str sizeWithFont:[UIFont fontWithName:@"Helvetica" size:17] constrainedToSize:CGSizeMake(280, 999) lineBreakMode:NSLineBreakByWordWrapping];
    NSLog(@"%f",size.height);
    return size.height + 10;
}

en dessous de la ligne, vous définissez le numéro de votre étiquette. de ligne à max. alors définissez-le dans cellForRowAtIndexPath: method.

cell.textLabel.numberOfLines = 0;

si vous utilisez une cellule personnalisée, gérez toutes les chaînes de l'étiquette avec ceci et obtenez la somme de toute cette hauteur, puis définissez la hauteur de votre cellule.

Edit: IOS 8 et versions ultérieures, si vous définissez les contraintes d'autolayout appropriées, vous devez définir uniquement la méthode de délégation suivante pour y parvenir.

-(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
   //minimum size of your cell, it should be single line of label if you are not clear min. then return UITableViewAutomaticDimension;    
   return UITableViewAutomaticDimension; 
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return UITableViewAutomaticDimension;
}

c'est ça. aucun calcul requis. Pour plus d'informations, consultez ce tutoriel.

56
AJPatel

Dans votre CustomCell: N'oubliez pas d'ajouter le contrainte en haut et en bas pour votre UILabel 

Pour ajuster la hauteur UILabel en fonction du texte, il suffit de changer la ligne UILabel en 0 ( voir la réponse ici)

Ensuite, dans votre code, ne définissez que 2 lignes

self.tableView.estimatedRowHeight = 80;
self.tableView.rowHeight = UITableViewAutomaticDimension;

Voici ma cellule personnalisée
 enter image description here Voici mes contraintes UILabel
 enter image description here
L’écran que vous allez réaliser

 enter image description here

=== Suggestion ===
SI votre cellule a une UILabels et une Images (pas comme mon exemple) alors:

  • Vous devez mettre tous les UILabels et Images dans un GroupView (Afficher) 
  • Ajoutez le constraint top and bottom to supper view pour cette GroupView (comme le UILabel dans mon image) 
  • Ajustez la hauteur UILabel comme ci-dessus ma suggestion 
  • Ajustez la hauteur GroupView en fonction du contenu (le contenu est entièrement UILabels et Images
  • Enfin, changez estimateRowHeight et tableView.rowHeight comme le code ci-dessus

J'espère que cette aide 

43
Linh

Pour Swift développeurs:

Cellule personnalisée : Au début, vous pouvez calculer la hauteur du texte comme ci-dessous:

func calculateHeight(inString:String) -> CGFloat
    {
        let messageString = inString
        let attributes : [String : Any] = [NSFontAttributeName : UIFont.systemFont(ofSize: 15.0)]

        let attributedString : NSAttributedString = NSAttributedString(string: messageString, attributes: attributes)

        let rect : CGRect = attributedString.boundingRect(with: CGSize(width: 222.0, height: CGFloat.greatestFiniteMagnitude), options: .usesLineFragmentOrigin, context: nil)

        let requredSize:CGRect = rect
        return requredSize.height
    }

Définissez la largeur de votre libellé de texte

Ensuite, appelez cette fonction:

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        heightOfRow = self.calculateHeight(inString: conversations[indexPath.row].description)

        return (heightOfRow + 60.0)
}

Pour Cellule de base :

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
           return UITableViewAutomaticDimension
    }

Cette fonction ne fonctionnera pas pour les cellules personnalisées.

J'espère que ça va marcher. 

5
mumu

Dans tableView:heightForRowAtIndexPath:, vous pouvez prendre le texte et utiliser sizeWithFont:constrainedToSize: pour obtenir la taille du texte.

Ensuite, il vous suffit de renvoyer la hauteur et un espacement supplémentaire pour le tampon.

2
Kevin Low

Vous pouvez écrire une méthode globalement pour qu'elle puisse être utilisée dans toute l'application. Vous devez passer le texte, la police et la largeur selon vos besoins.

Dans Swift 4:

func heightForText(text: String,Font: UIFont,Width: CGFloat) -> CGFloat{

    let constrainedSize = CGSize.init(width:Width, height: CGFloat(MAXFLOAT))

    let attributesDictionary = NSDictionary.init(object: Font, forKey:NSAttributedStringKey.font as NSCopying)

    let mutablestring = NSAttributedString.init(string: text, attributes: attributesDictionary as? [NSAttributedStringKey : Any])

    var requiredHeight = mutablestring.boundingRect(with:constrainedSize, options: NSStringDrawingOptions.usesFontLeading.union(NSStringDrawingOptions.usesLineFragmentOrigin), context: nil)

    if requiredHeight.size.width > Width {
        requiredHeight = CGRect.init(x: 0, y: 0, width: Width, height: requiredHeight.height)

    }
    return requiredHeight.size.height;
}
1
Harry P
NSString *str;
NSArray* dictArr;

if (_index==0) {
    dictArr = mustangCarDetailDictArr[indexPath.section];

}

NSDictionary* dict = dictArr[indexPath.row];


if (indexPath.section ==0)
{

    str = [dict valueForKey:@"FeatureName"];
    if ([[dict valueForKey:@"FeatureDetail"] isKindOfClass:[NSString class]])
    {

        str = [dict valueForKey:@"FeatureDetail"];



    }
    else
    {
        if (dictArr.count>indexPath.row+1)
        {
            NSDictionary* dict2 = dictArr[indexPath.row+1];
            if ([[dict2 valueForKey:@"FeatureDetail"] isKindOfClass:[NSString class]])
            {


            }
        }

    }


}
CGSize size = [str sizeWithFont:[UIFont fontWithName:@"Helvetica" size:17] constrainedToSize:CGSizeMake(280, 999) lineBreakMode:NSLineBreakByWordWrapping];
NSLog(@"%f",size.height);
return size.height + 20;


}
0

J'ai pu obtenir ce résultat en utilisant l'autolayout. Assurez-vous que votre étiquette se positionne en haut et en bas de la cellule (j'utilise une cellule prototype) et que ses lignes sont définies sur 0. Ensuite, dans le tableView:heightForRowAtIndexPath:sizeWithFont:constrainedToSize:, vous pouvez définir la hauteur de la cellule en calculant la taille du texte. :

NSString *key = self.detailContent.allKeys[indexPath.row];
NSDictionary *dictionary = self.detailContent[key];
NSString *cellText = dictionary[kSMDetailTableViewCellTextKey];
UIFont *cellFont = [UIFont fontWithName:kFontKeyEmondsans size:12.0];
CGSize constraintSize = CGSizeMake(252.0f, MAXFLOAT);
CGSize labelSize = [cellText sizeWithFont:cellFont constrainedToSize:constraintSize lineBreakMode:NSLineBreakByWordWrapping];
return labelSize.height;// + 10;
0
VaporwareWolf