web-dev-qa-db-fra.com

Dimensionnement d'un UILabel pour l'adapter?

Comment modifier l'extrait suivant (dans une méthode tableView: cellForRowAtIndexPath: UITableViewController) à partir de la recette "09a - PrefsTable" du chapitre 6 du livre de recettes du développeur iPhone:

if (row == 1) { 
    // Create a big Word-wrapped UILabel 
    cell = [tableView dequeueReusableCellWithIdentifier:@"libertyCell"]; 
    if (!cell) { 
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:@"libertyCell"] autorelease]; 
        [cell addSubview:[[UILabel alloc] initWithFrame:CGRectMake(20.0f, 10.0f, 280.0f, 330.0f)]]; 
    } 
    UILabel *sv = [[cell subviews] lastObject]; 
    sv.text =  @"When in the Course of human events, it becomes necessary for one people to dissolve the political bands which have connected them with another, and to assume among the powers of the earth, the separate and equal station to which the Laws of Nature and of Nature's God entitle them, a decent respect to the opinions of mankind requires that they should declare the causes which impel them to the separation."; 
    sv.textAlignment = UITextAlignmentCenter; 
    sv.lineBreakMode = UILineBreakModeWordWrap; 
    sv.numberOfLines = 9999; 
    return cell; 
} 

... pour redimensionner la sous-vue "sv" UILabel et la "cellule" UITableViewCell afin qu'elles soient assez grandes pour contenir le texte (et fonctionnent avec plus ou moins de texte et d'autres types d'alignement de texte)? J'ai examiné la méthode UILabel textRectForBounds: limitedToNumberOfLines:, mais la documentation indique qu'elle ne doit pas être appelée directement (et doit uniquement être remplacée). J'ai expérimenté la méthode UIView sizeToFit, sans succès.

Mise à jour:J'ai posé une nouvelle question à propos de mon problème avec NSString -sizeWithFont: forWidth: lineBreakMode: method .

43
Daryl Spitzer

Je devais le faire assez pour que je demande à UILabel de le faire pour moi:

@interface UILabel (BPExtensions)
- (void)sizeToFitFixedWidth:(CGFloat)fixedWidth;
@end

@implementation UILabel (BPExtensions)


- (void)sizeToFitFixedWidth:(CGFloat)fixedWidth
{
    self.frame = CGRectMake(self.frame.Origin.x, self.frame.Origin.y, fixedWidth, 0);
    self.lineBreakMode = NSLineBreakByWordWrapping;
    self.numberOfLines = 0;
    [self sizeToFit];
}
@end

alors d'avoir une étiquette pour avoir une hauteur multiligne variable mais une largeur fixe simplement:

[myLabel sizeToFitFixedWidth:kSomeFixedWidth];

98
BadPirate

Vous devez utiliser la méthode -sizeWithFont:forWidth:lineBreakMode: de NSString pour récupérer les métriques de dimensionnement associées pour votre étiquette.

17
Lily Ballard

Modifiez également la propriété numberOfLines en 0 si vous comptez utiliser ce code.

10
Sophie Alpert

NSString 's -sizeWithFont:forWidth:lineBreakMode: n'effectue pas réellement le retour à la ligne. Utilisez plutôt -sizeWithFont:constrainedToSize:lineBreakMode: pour obtenir une valeur de largeur ET hauteur précise pour la chaîne.

5
pix0r

Essaye ça:

sv.text =  @"When in the Course of human events, it becomes necessary for one people to dissolve the political bands which have connected them with another, and to assume among the powers of the earth, the separate and equal station to which the Laws of Nature and of Nature's God entitle them, a decent respect to the opinions of mankind requires that they should declare the causes which impel them to the separation."; 
sv.textAlignment = UITextAlignmentCenter; 
sv.lineBreakMode = UILineBreakModeWordWrap; 
sv.numberOfLines = 0;
[sv sizeToFit]; 
4
Sebastian

De plus, vous devrez implémenter la méthode UITableViewDelegate:

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

Et demandez-lui de renvoyer une hauteur totale de cellule ajustée pour le champ de texte redimensionné.

Une autre remarque - Size to Fit devrait réellement fonctionner si vous avez défini le nombre de lignes sur 0, comme indiqué précédemment. Cela vous redonnerait une taille avec la hauteur augmentée pour s'adapter au texte enveloppé de mots défini dans l'étiquette et la largeur définie quelle que soit la largeur de l'étiquette d'origine.

Cela ne vous aidera pas car vous devez obtenir la taille en heightForRow avant que la cellule ne soit obtenue, il est donc préférable de calculer la hauteur nécessaire (et très probablement de mettre en cache ce calcul pour ne pas ralentir le rendu de la table)

Voici un peu de code que j'utilise:

CGSize textSize = [myLabel.text sizeWithFont:myLabel.font];
1
Chris

J'ai eu le même problème ... J'ai résolu ça.

Dans la méthode cellForRowAtIndexPath, définissez la taille de la police comme bon vous semble.

cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
cell.textLabel.numberOfLines = 0;    
[cell.textLabel setFont:[UIFont systemFontOfSize:14.0]];
[cell.textLabel sizeToFit];

Et dans la méthode heightForRowAtIndexPath, augmentez la taille de la police.

    CGFloat height;

    UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
    NSString *text = cell.detailTextLabel.text;
    CGSize constraint = CGSizeMake(320, 20000.0f);
    CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:20.0]     constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
    CGFloat calHeight = MAX(size.height, 44.0f);
    height =  calHeight + (CELL_CONTENT_MARGIN * 2);

    return height;
0
iPhoneDev

J'ai eu un problème similaire, j'avais un UITableViewCell qui a été conçu dans StoryBoards comme une cellule statique. J'ai utilisé [super tableView:cellForRowAtIndexPath:] pour l'obtenir. Je voulais donc redimensionner le "detailTextLabel" UILabel afin qu'il corresponde au texte que je lui ai attribué. Le style était "Right Detail".

Je viens de définir le texte dans mon tableView:cellForRowAtIndexPath:. Et que dans tableView:heightForRowAtIndexPath: je suis revenu 

UITableViewCell *cell = [super tableView:tableView cellForRowAtIndexPath:indexPath];
return cell.detailTextLabel.frame.size.height

J'ai eu une longue ficelle. Et enfin, avait une large cellule avec 4 lignes de texte dans l'étiquette.

0
DanSkeel