Comment encapsuler du texte dans un UITableViewCell sans cellule personnalisée

151

C'est sur l'iPhone 0S 2.0. Les réponses pour 2.1 sont également très bien, bien que je ne connaisse aucune différence concernant les tableaux.

Il semble qu'il devrait être possible d'obtenir du texte à envelopper sans créer de cellule personnalisée, car a UITableViewCellcontient un UILabelpar défaut. Je sais que je peux le faire fonctionner si je crée une cellule personnalisée, mais ce n'est pas ce que j'essaie de réaliser - je veux comprendre pourquoi mon approche actuelle ne fonctionne pas.

J'ai compris que l'étiquette est créée à la demande (puisque la cellule prend en charge l'accès au texte et à l'image, elle ne crée donc pas la vue des données tant que cela n'est pas nécessaire), donc si je fais quelque chose comme ceci:

cell.text = @""; // create the label
UILabel* label = (UILabel*)[[cell.contentView subviews] objectAtIndex:0];

alors j'obtiens une étiquette valide, mais le réglage numberOfLinessur cela (et lineBreakMode) ne fonctionne pas - j'obtiens toujours du texte sur une seule ligne. Il y a beaucoup de hauteur dans le UILabeltexte à afficher - je renvoie simplement une grande valeur pour la hauteur dans heightForRowAtIndexPath.

Airsource Ltd
la source

Réponses:

277

Voici un moyen plus simple, et cela fonctionne pour moi:

À l'intérieur de votre cellForRowAtIndexPath:fonction. La première fois que vous créez votre cellule:

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];
}

Vous remarquerez que j'ai mis le nombre de lignes pour l'étiquette à 0. Cela lui permet d'utiliser autant de lignes qu'il en a besoin.

La partie suivante consiste à spécifier la taille de votre UITableViewCellvolonté, alors faites-le dans votre heightForRowAtIndexPathfonction:

- (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;
}

J'ai ajouté 20 à la hauteur de ma cellule renvoyée car j'aime un petit tampon autour de mon texte.

Tim Rupe
la source
17
Vous n'avez pas besoin de définir votre cell.textLabel.numberOfLines sur un nombre arbitrairement élevé. Le mettre à 0 signifie «autant de lignes qu'il faut pour afficher».
mmc
Merci, je modifierai mon message ce soir après avoir eu la chance de le vérifier dans mon propre projet.
Tim Rupe
1
Définir le nombre de lignes sur 0 fonctionne très bien (autant de lignes qu'il faut pour afficher)
prakash
1
cagreen: Il s'avère que je peux reproduire cela, mais seulement si j'utilise iPhone OS 3.0 dans le simulateur. Lorsque j'utilise 3.1+, le redimensionnement de detailTextLabel correspond parfaitement à celui de sizeWithFont. La méthode de Tim fonctionne donc très bien - juste pour 3.1+ (probablement en raison d'un bogue / d'un dysfonctionnement dans le rendu de cellule par défaut 3.0). Pour mémoire, j'utilise une marge verticale haut / bas de 12 (chacun), une taille d'étiquette de texte détaillée de (188.0, CGFLOAT_MAX) et un boldSystemFontOfSize 15.
Joe D'Andrea
17
UILineBreakModeWordWrap est obsolète dans iOS 6. Utilisez plutôt NSLineBreakByWordWrapping.
Ethan Allen
16

Mise à jour de la réponse de Tim Rupe pour iOS7:

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

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *cellText = @"Go get some text for your cell.";
    UIFont *cellFont = [UIFont fontWithName:@"Helvetica" size:17.0];

    NSAttributedString *attributedText =
        [[NSAttributedString alloc]
            initWithString:cellText
            attributes:@
            {
                NSFontAttributeName: cellFont
            }];
    CGRect rect = [attributedText boundingRectWithSize:CGSizeMake(tableView.bounds.size.width, CGFLOAT_MAX)
                                               options:NSStringDrawingUsesLineFragmentOrigin
                                               context:nil];
    return rect.size.height + 20;
}
ddiego
la source
3

Un bref commentaire / réponse pour enregistrer mon expérience lorsque j'ai eu le même problème. Malgré l'utilisation des exemples de code, la hauteur de la cellule de la vue tableau s'ajustait, mais l'étiquette à l'intérieur de la cellule ne s'ajustait toujours pas correctement - la solution était que je chargeais ma cellule à partir d'un fichier NIB personnalisé, ce qui se produit une fois la hauteur de cellule ajustée.

Et j'avais mes paramètres dans le fichier NIB pour ne pas envelopper le texte, et n'avoir qu'une ligne pour l'étiquette; les paramètres du fichier NIB remplaçaient les paramètres que j'avais ajustés à l'intérieur du code.

La leçon que j'ai prise était de m'assurer de toujours garder à l'esprit l'état des objets à chaque instant - ils n'ont peut-être pas encore été créés! ... hth quelqu'un sur toute la ligne.

Richard Le Mesurier
la source
2

Si nous devons ajouter uniquement du texte dans la UITableViewcellule, nous n'avons besoin que de deux délégués pour travailler (pas besoin d'ajouter des éléments supplémentaires UILabels)

1) cellForRowAtIndexPath

2) heightForRowAtIndexPath

Cette solution a fonctionné pour moi: -

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
{ 
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil)
    {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }

    cell.textLabel.font = [UIFont fontWithName:@"Helvetica" size:16];
    cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
    cell.textLabel.numberOfLines = 0;

    [cell setSelectionStyle:UITableViewCellSelectionStyleGray]; 
    cell.textLabel.text = [mutArr objectAtIndex:indexPath.section];
    NSLog(@"%@",cell.textLabel.text);

    cell.accessoryView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"arrow.png" ]];

    return cell;

}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{  
    CGSize labelSize = CGSizeMake(200.0, 20.0);

    NSString *strTemp = [mutArr objectAtIndex:indexPath.section];

    if ([strTemp length] > 0)
        labelSize = [strTemp sizeWithFont: [UIFont boldSystemFontOfSize: 14.0] constrainedToSize: CGSizeMake(labelSize.width, 1000) lineBreakMode: UILineBreakModeWordWrap];

    return (labelSize.height + 10);
}

Ici, la chaîne mutArrest un tableau mutable à partir duquel je récupère mes données.

EDIT: - Voici le tableau que j'ai pris.

mutArr= [[NSMutableArray alloc] init];

[mutArr addObject:@"HEMAN"];
[mutArr addObject:@"SUPERMAN"];
[mutArr addObject:@"Is SUPERMAN powerful than HEMAN"];
[mutArr addObject:@"Well, if HEMAN is weaker than SUPERMAN, both are friends and we will never get to know who is more powerful than whom because they will never have a fight among them"];
[mutArr addObject:@"Where are BATMAN and SPIDERMAN"];
Arshad Parwez
la source
2

Désormais, les vues de table peuvent avoir des cellules auto-dimensionnées. Configurez la vue de la table comme suit

tableView.estimatedRowHeight = 85.0 //use an appropriate estimate tableView.rowHeight = UITableViewAutomaticDimension

Référence Apple

Jason
la source
0

J'utilise les solutions suivantes.

Les données sont fournies séparément dans un membre:

-(NSString *)getHeaderData:(int)theSection {
    ...
    return rowText;
}

La manipulation peut être facilement effectuée cellForRowAtIndexPath. Définissez la cellule / définissez la police et attribuez ces valeurs au résultat "cellule". Notez que le numberoflinesest mis à "0", ce qui signifie prendre ce qui est nécessaire.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    UIFont *cellFont = [UIFont fontWithName:@"Verdana" size:12.0];
    cell.textLabel.text= [self getRowData:indexPath.section];
    cell.textLabel.font = cellFont;
    cell.textLabel.numberOfLines=0;
    return cell;
}

Dans heightForRowAtIndexPath, je calcule les hauteurs du texte enveloppé. La taille du corsage doit être liée à la largeur de votre cellule. Pour iPad, ce sera 1024. Pour iPhone et iPod 320.

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UIFont *cellFont = [UIFont fontWithName:@"Verdana" size:12.0];
    CGSize boundingSize = CGSizeMake(1024, CGFLOAT_MAX);
    CGSize requiredSize = [[self getRowData:indexPath.section] sizeWithFont:cellFont constrainedToSize:boundingSize lineBreakMode:UILineBreakModeWordWrap];
    return requiredSize.height;    
}
Vincent
la source
0

J'ai trouvé cela assez simple et direct.

[self.tableView setRowHeight:whatEvereight.0f];

par exemple:

[self.tableView setRowHeight:80.0f];

Cela peut être ou non la meilleure approche / standard pour le faire, mais cela a fonctionné dans mon cas.

Manish Kr. Shukla
la source
Si je comprends bien, la propriété rowHeight définit une hauteur fixe qui sera utilisée pour toutes les cellules de la vue tableau. L'utilisation de rowHeight est meilleure pour les performances dans les grands tableaux, mais si vous avez besoin que la hauteur de chaque cellule varie en fonction de son contenu, il semble que la méthode tableView: heightForRowAtIndexPath: doit être utilisée.
jk7
0

Essayez mon code rapidement. Ce code fonctionnera également pour les étiquettes UIL normales.

extension UILabel {
    func lblFunction() {
        //You can pass here all UILabel properties like Font, colour etc....
        numberOfLines = 0
        lineBreakMode = .byWordWrapping//If you want word wraping
        lineBreakMode = .byCharWrapping//If you want character wraping
    }
}

Maintenant, appelez simplement comme ça

cell.textLabel.lblFunction()//Replace your label name 
iOS
la source
-1

Je pense que c'est une solution meilleure et plus courte. Formatez simplement le UILabel( textLabel) de la cellule pour calculer automatiquement la hauteur en spécifiant sizeToFitet tout devrait bien se passer.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil)
    {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
    }

    // Configure the cell...
    cell.textLabel.text = @"Whatever text you want to put here is ok";
    cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
    cell.textLabel.numberOfLines = 0;
    [cell.textLabel sizeToFit];

    return cell;
}
dukz
la source
-2

Je ne pense pas que vous puissiez manipuler une base UITableViewCell'sprivée UILabelpour faire cela. Vous pouvez en ajouter vous-même une nouvelle UILabelà la cellule et l'utiliser numberOfLinesavec sizeToFitpour la dimensionner de manière appropriée. Quelque chose comme:

UILabel* label = [[UILabel alloc] initWithFrame:cell.frame];
label.numberOfLines = <...an appriate number of lines...>
label.text = <...your text...>
[label sizeToFit];
[cell addSubview:label];
[label release];
drewh
la source