2009-07-15 11 views
19

J'utilise UITableView avec des cellules créées à l'aide de UITableViewCellStyleSubtitle. La hauteur de chaque cellule est ajustée dynamiquement à l'aide de la méthode déléguéeEtiquettes alignées dans UITableViewCell

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

.

Le problème que vous pouvez voir sur l'image

( Note: l'image mise à jour)

http://img.skitch.com/20090715-g7srxgee2d7fhi5rab2wufrdgm.png

Comment mettre en place align des Textlabel et detailTextLabel au sommet de la cellule ? (Je ne pas coutume de le faire par le sous-classement UITableViewCell et layoutSubviews prépondérants)

Thanx

+0

Il semble que le texte de votre sous-titre circule dans le bas de la cellule et dans le suivant, est-ce que c'est ce que je vois? Aussi, cela arrive-t-il sur l'appareil ou juste sur simulateur? – jbrennan

+0

Pouvez-vous poster votre implémentation de heightForRowAtIndexPath? –

+4

Belle touche avec la capture d'écran. –

Répondre

8

Voici une autre solution sans sous-classe de cellules, donc cela fonctionne certainement avec différents styles de tables. (Je n'ai pas vérifié d'autres solutions.) Les chaînes de titre et de détail sont déclarées dans mon en-tête UITableViewController et déjà définies. Ils ne sont pas très longs, certainement bien en hauteur 4000!

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

    CGRect frame = [UIScreen mainScreen].bounds; 
    CGFloat width = frame.size.width; 

    int section = indexPath.section; 
    int row = indexPath.row; 

    NSString *title_string = [title_strings_array objectAtIndex:row]; 
    NSString *detail_string = [detail_strings_array objectAtIndex:row]; 

    CGSize title_size = {0, 0}; 
    CGSize detail_size = {0, 0}; 

    if (title_string && [title_string isEqualToString:@""] == NO) { 
     title_size = [title_string sizeWithFont:[UIFont systemFontOfSize:22.0] 
           constrainedToSize:CGSizeMake(width, 4000) 
            lineBreakMode:UILineBreakModeWordWrap]; 
    } 

    if (detail_string && [title_string isEqualToString:@""] == NO) { 
     detail_size = [detail_string sizeWithFont:[UIFont systemFontOfSize:18.0] 
           constrainedToSize:CGSizeMake(width, 4000) 
            lineBreakMode:UILineBreakModeWordWrap]; 
    } 

    CGFloat title_height = title_size.height; 
    CGFloat detail_height = detail_size.height; 

    CGFloat content_size = title_height + detail_height; 

    CGFloat height; 

    switch (section) { 

     case 0: 
      height = content_size; 
      break; 

     //Just in case 
     default: 
      height = 44.0; 
      break; 

    } 

    return height; 

} 
1

Cependant, vous soupèsent vos cellules, vous devriez le faire avec les différentes méthodes de dimensionnement de NSString. De cette façon, vous pouvez déterminer exactement la hauteur de la cellule et éviter les espaces.

36

Eh bien, celui-ci m'a coûté un après-midi, mais je pense que je l'ai compris. Autant que je sache, cela semble être un bug dans la façon dont UITableViewCell est en train de mettre en page textLabel et detailTextLabel. Lorsque vous définissez la hauteur de ligne, il semble attribuer une hauteur égale aux deux étiquettes, ce qui signifie que vous obtenez exactement le comportement que vous voyez ci-dessus, même si detailTextLabel a besoin de plus d'espace. Voici les deux choses que j'ai faites pour résoudre le problème. J'ai dû sous-classer UITableViewCell pour le réparer, mais c'est une quantité minimale de code. Tout d'abord, assurez-vous de calculer correctement la hauteur de chaque rangée. Mettez cette méthode dans votre délégué de vue de table. Remettez en place les méthodes de police avec votre propre:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    NSString *cellDetailText = [[self itemForIndexPath: indexPath] detailDescription]; 
    NSString *cellText = [[self itemForIndexPath: indexPath] description]; 
    // The width subtracted from the tableView frame depends on: 
    // 40.0 for detail accessory 
    // Width of icon image 
    // Editing width 
    // I don't think you can count on the cell being properly laid out here, so you've 
    // got to hard code it based on the state of the table. 
    CGSize constraintSize = CGSizeMake(tableView.frame.size.width - 40.0 - 50.0, CGFLOAT_MAX); 
    CGSize labelSize = [cellText sizeWithFont: [self cellTextLabelFont] constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap]; 
    CGSize detailSize = [cellDetailText sizeWithFont: [self cellDetailTextLabelFont] constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap]; 

    CGFloat result = MAX(44.0, labelSize.height + detailSize.height + 12.0); 
    return result; 
} 

Ensuite, la sous-classe UITableViewCell et passer outre layoutSubviews:

#import "UITableViewCellFixed.h" 


@implementation UITableViewCellFixed 
- (void) layoutSubviews { 
    [super layoutSubviews]; 
    self.textLabel.frame = CGRectMake(self.textLabel.frame.origin.x, 
             4.0, 
             self.textLabel.frame.size.width, 
             self.textLabel.frame.size.height); 
    self.detailTextLabel.frame = CGRectMake(self.detailTextLabel.frame.origin.x, 
              8.0 + self.textLabel.frame.size.height, 
              self.detailTextLabel.frame.size.width, 
              self.detailTextLabel.frame.size.height); 
} 
@end 
+1

Grande réponse, a parfaitement fonctionné. Nice touch: remplacez 4.0 par 12.0 si detailTextLabel.text == nil pour centrer textLabel verticalement dans la vue lorsqu'il n'y a pas de detailText pour la cellule. –

+0

C'est woks comme un charme! – wal

+0

Ceci est une astuce vraiment utile. Merci! –

-2

S'il apparaît que la Textlabel et detailTextLabel sont disposés à l'aide de masques de redimensionnement automatique, vous pouvez peut-être faire Lorsque vous retournez la cellule:

cell.textLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleBottomMargin; 
cell.detailTextLabel.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 

Si cela fonctionne, c'est un peu plus facile que de sous-classer la cellule. Je n'ai pas essayé cependant.

+0

Bien sûr, c'est facile, mais ça ne marche pas. layoutSubviews-overriding est la bonne façon. – slatvick

Questions connexes