web-dev-qa-db-fra.com

uITableView Cell iOS 7/8: deux étiquettes UIL à hauteur dynamique avec présentation automatique pour une hauteur de ligne variable

Je peux donc configurer le dimensionnement dynamique en hauteur avec la mise en page automatique lorsque je ne dispose que d’une seule étiquette qui modifie la hauteur en fonction de la longueur de la chaîne. , les choses ne fonctionnent pas. 

Je règle à la fois la priorité Content Hugging et la résistance à la compression sur 1000 == Je reçois des avertissements d'ambiguïté. 

Si je règle le calage du contenu (vertical) pour le deuxième UILabel sur 999 ou 250, cela fonctionnera très bien, mais uniquement si le deuxième label a 2 lignes ou plus. Si la deuxième étiquette est vide ou ne comporte qu'une seule ligne, la hauteur heightForRowAtIndexPath systemLayoutSizeFittingSize: UILayoutFittingCompressedSize renvoie des valeurs élevées et les cellules comportent des espaces vides. 

J'ai également joué avec Intrinsic Size: Default ou Placeholder (avec quelques hauteurs et largeurs) mais cela n'aide pas non plus. 

Quelqu'un a des suggestions que peut-on faire?

15
Zsolt

Je l'ai fait fonctionner finalement. Pour moi, la solution consistait à définir explicitement la largeur préférée par rapport à la largeur actuelle du cadre. Donc, cochez la case Explicite dans l’étiquette> Largeur préférée dans l’inspecteur de taille.

ref: http://www.raywenderlich.com/73602/dynamic-table-view-cell-height-auto-layout Téléchargez l'exemple de code et visualisez la configuration du storyboard. 

18
Zsolt

Pour moi, il a fallu combiner plusieurs choses.

  • Outre le réglage correct du contenu et de la résistance
  • Je devais faire une sous-classe de UILabel pour gérer le preferredMaxLayoutWidth de l'étiquette 
  • et corrige aussi un bogue dans intrinsicContentSize

La sous-classe UILabel a fini par ressembler à ceci:

@implementation LabelDynamicHeight

- (void)layoutSubviews
{
    [super layoutSubviews];

    self.preferredMaxLayoutWidth = self.frame.size.width;

    [super layoutSubviews];
}

- (void)setBounds:(CGRect)bounds
{
    [super setBounds:bounds];

    if (self.numberOfLines == 0)
    {
        CGFloat boundsWidth = CGRectGetWidth(bounds);
        if (self.preferredMaxLayoutWidth != boundsWidth)
        {
            self.preferredMaxLayoutWidth = boundsWidth;
            [self setNeedsUpdateConstraints];
        }
    }
}

- (CGSize)intrinsicContentSize
{
    CGSize size = [super intrinsicContentSize];

    if (self.numberOfLines == 0)
    {
        // There's a bug where intrinsic content size may be 1 point too short
        size.height += 1;
    }

    return size;
}

@end

En plus de cet appel, layoutIfNeeded sur la cellule avant d’obtenir la hauteur dans tableView heightForRowAtIndexPath: a rendu les contraintes prêtes avant l’utilisation de la méthode systemLayoutSizeFittingSize: sur le contentView. Ressemblant à ceci:

- (CGFloat)tableView:( UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = ...;
    CGFloat height = cell.frame.size.height;
    if (cell.dynamicHeight)
    {
        // https://stackoverflow.com/a/26351692/1840269
        [cell layoutIfNeeded];
        height = cell.frame.size.height;

        CGSize size = [cell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
        if (size.height > height)
            height = size.height;
    }
    return height;
}

Références:

1
micmdk

Pour moi, définir une priorité de contenu et une priorité de résistance de compression de contenu inférieures à l'un des éléments a fonctionné comme prévu.

0
Raj Pawan Gumdal