web-dev-qa-db-fra.com

pourquoi UITableViewAutomaticDimension ne fonctionne pas?

Bonjour, il y a beaucoup de questions pour répondre à la hauteur dynamique de UITableViewCell de UITableView. Cependant, je trouve ça bizarre quand je l'ai fait.

voici quelques unes des réponses:

ici et ici

généralement cela répondrait à la hauteur dynamique de la cellule

tableView.estimatedRowHeight = 44.0
tableView.rowHeight = UITableViewAutomaticDimension

mais dans mon cas, je me demande si cette ligne ne fera rien.

ma UITableView est affichée après avoir cliqué sur la barre de tabulation à l'intérieur de la vue partagée. Est-ce utile? 

Peut-être que je manque quelque chose. Quelqu'un pourrait-il m'aider, j'ai passé 2 heures à faire des bêtises. 

Ce sont mes contraintes pour le titre: le titre peut être long mais l'étiquette ne l'est pas.

enter image description here

et ceci est ma cellule

enter image description here

56
CaffeineShots

Pour que UITableViewAutomaticDimension fonctionne, vous devez définir toutes les contraintes gauche, droite, inférieure et supérieure relatives à la vue du conteneur de cellules. Dans votre cas, vous devrez ajouter l'espace inférieur manquant à la contrainte superview pour l'étiquette sous le titre.

126
Zell B.

J'avais ajouté des contraintes par programme et les ai ajoutées accidentellement directement à la cellule, c'est-à-dire pas sur la propriété contentView. L'ajout des contraintes à contentView l'a résolu pour moi!

21
Eyeball

Assurez-vous également que les lignes de votre UILabel dans la cellule sont définies sur 0. Si la valeur est définie sur 1, le développement ne sera pas vertical. 

16
CamQuest

Pour définir la dimension automatique pour la hauteur de ligne et la hauteur estimée de la ligne, assurez-vous que les étapes suivantes permettent de rendre la cote automatique effective pour la présentation de hauteur de cellule/ligne. 

  • Affecter et mettre en œuvre tableview dataSource et déléguer
  • Attribuez UITableViewAutomaticDimension à rowHeight & installedRowHeight
  • Implémenter des méthodes delegate/dataSource (c'est-à-dire heightForRowAt et lui renvoyer une valeur UITableViewAutomaticDimension)

-

Objectif c:

// in ViewController.h
#import <UIKit/UIKit.h>

@interface ViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>

  @property IBOutlet UITableView * table;

@end

// in ViewController.m

- (void)viewDidLoad {
    [super viewDidLoad];
    self.table.dataSource = self;
    self.table.delegate = self;

    self.table.rowHeight = UITableViewAutomaticDimension;
    self.table.estimatedRowHeight = UITableViewAutomaticDimension;
}

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

    return UITableViewAutomaticDimension;
}

Rapide:

@IBOutlet weak var table: UITableView!

override func viewDidLoad() {
    super.viewDidLoad()

    // Don't forget to set dataSource and delegate for table
    table.dataSource = self
    table.delegate = self

    // Set automatic dimensions for row height
    // Swift 4.2 onwards
    table.rowHeight = UITableView.automaticDimension
    table.estimatedRowHeight = UITableView.automaticDimension


    // Swift 4.1 and below
    table.rowHeight = UITableViewAutomaticDimension
    table.estimatedRowHeight = UITableViewAutomaticDimension

}



// UITableViewAutomaticDimension calculates height of label contents/text
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    // Swift 4.2 onwards
    return UITableView.automaticDimension

    // Swift 4.1 and below
    return UITableViewAutomaticDimension
}

Pour l'instance d'étiquette dans UITableviewCell

  • Définir le nombre de lignes = 0 (& mode de saut de ligne = tronquer la queue)
  • Définissez toutes les contraintes (haut, bas, droite à gauche) par rapport à son conteneur superview/cell.
  • Facultatif: définissez la hauteur minimale de l'étiquette, si vous voulez une zone verticale minimale couverte par l'étiquette, même s'il n'y a pas de données.

enter image description here

Remarque : Si vous avez plusieurs étiquettes (UIElements) avec une longueur dynamique, ajustez-les en fonction de la taille de son contenu: Ajustez la priorité de rétention de compression et de compression du contenu pour les étiquettes avec lesquelles vous souhaitez développer/compresser priorité plus élevée.

14
Krunal

Depuis iOS 11 et Xcode 9.3, la plupart des informations ci-dessus sont fausses. Guide d'Apple suggère un réglage

    tableView.estimatedRowHeight = 85.0
    tableView.rowHeight = UITableViewAutomaticDimension

WWDC 2017 session 245 (Création d'applications avec le type dynamique, environ 16:33 dans la vidéo) suggère quelque chose de similaire. Rien de tout cela n'a fait de différence pour moi.

Pour une cellule de style Sous-titre, il suffit de définir le nombre de lignes (dans la section Étiquette de l'inspecteur d'attributs) sur 0 pour le titre et le sous-titre. Si l'une de ces étiquettes est trop longue et que vous ne définissez pas le nombre de lignes sur 0, la cellule de la vue tableau ne modifiera pas sa taille.

4
Zampano

J'ai un cas spécifique et 99% des solutions que j'ai lues n'ont pas fonctionné. Je pensais partager mon expérience. J'espère que cela peut aider, car j'avais eu du mal à résoudre ce problème pendant quelques heures. 

Mon scénario

  • J'utilise deux TableViews dans un ViewController
  • Je suis charge des cellules personnalisées (xib) dans ces vues de table
  • Le contenu dynamique dans les cellules est constitué de deux étiquettes
  • La page utilise un ScrollView

Ce qu'il me fallait pour réussir:

  • Hauteur de table dynamique
  • Hauteur de TableViewCells dynamique

Ce que vous devrez vérifier pour que tout se passe bien:

  • Comme chaque tutoriel et chaque réponse vous le diront, définissez toutes les contraintes pour votre étiquette/contenu (haut, bas, premier et dernier) et définissez-le sur ContentView (Superview). Ce tutoriel vidéo sera utile .

  • Dans la méthode viewWillAppear de mon ViewController, je donne à l'une de mes tablesVue (tableView2) une hauteur de ligne estimée, puis j'utilise la UITableViewAutomaticDimension en tant que telle (et comme dans tous les tutoriels/réponses): 

        override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
    
        tableView2.estimatedRowHeight = 80
        tableView2.rowHeight = UITableViewAutomaticDimension
    
    }
    

Pour moi, ces étapes précédentes n'étaient pas suffisantes. Mon TableView prend simplement l'estimation de la propriété Row et le multiplie par le nombre de cellules. Meeeh.

  • Comme j'utilise deux tables différentes, j'ai créé une sortie pour chacune d'elles, tableView1 et tableView2. Cela me permet de les redimensionner dans la méthode viewDidLayoutSubviews. N'hésitez pas à demander en commentaire comment j'ai fait cela.

  • Une étape supplémentaire a corrigé cela pour moi, en ajoutant ceci à la méthode viewDidAppear:

    override func viewDidAppear(_ animated: Bool) {
    tableView1.reloadData() // reloading data for the first tableView serves another purpose, not exactly related to this question.
    tableView2.setNeedsLayout()
    tableView2.layoutIfNeeded()
    tableView2.reloadData()
    }
    

J'espère que ça aide quelqu'un!

4
Bptstmlgt

Oublié d'enlever tableView(heightForRowAt:indexPath:)

Il se peut que, comme moi, vous ayez accidentellement oublié de supprimer le code standard pour la méthode heightForRowAt

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return 60.0
}
3
Guy Daher

Essayez ceci, solution simple c'est travail pour moi,

Dans viewDidLoad, écrivez ce code,

-(void)viewDidLoad 
{
[super viewDidLoad];
 self.tableView.estimatedRowHeight = 100.0; // for example. Set your average height
 self.tableView.rowHeight = UITableViewAutomaticDimension;
}

Dans cellForRowAtIndexPath, écrivez ce code,  

 -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
 {
  static NSString *CellIdentifier = @"Cell";
  UITableViewCell *cell = [tableView 
  dequeueReusableCellWithIdentifier:CellIdentifier];
 if (cell == nil) {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] ;
  }
    cell.textLabel.numberOfLines = 0; // Set label number of line to 0
    cell.textLabel.text=[[self.arForTable objectAtIndex:indexPath.row] valueForKey:@"menu"];
    [cell.textLabel sizeToFit]; //set size to fit 
    return cell;
 }
2
Jaywant Khedkar

Dans mon cas, j’avais deux UITableViews, j’ai dû modifier cette méthode comme

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
    CGFloat height = 0.0;
    if (tableView == self.tableviewComments) {
        return UITableViewAutomaticDimension;
    }else if (tableView == self.tableViewFriends) {
        height = 44.0;
    }
    return height;
}
2
user1994956

Pour tous ceux qui ont peut-être rencontré le même problème avec moi: j'ai lutté pendant une heure pour que cela fonctionne. Un simple UIlabel avec des contraintes en haut, en bas à gauche et à droite. J'ai utilisé willDisplayCell pour transmettre les données à la cellule, ce qui posait des problèmes de hauteur des cellules. Tant que j'ai mis ce code dans cellForRow, tout a bien fonctionné. Je ne comprenais pas pourquoi cela était arrivé, peut-être que la hauteur de la cellule avait été calculée avant l'appel de willDisplayCell, de sorte qu'il n'y avait pas de contenu à faire le bon calcul. Je voulais juste mentionner et probablement aider quelqu'un avec le même problème.

1
Thomas

Pour ma configuration, j’ai d’abord vérifié deux fois que les contraintes dans le Storyboard pour la UITableViewCell étaient sans ambiguïté de haut en bas, puis je devais modifier le code à deux endroits. 

  1. UITableViewDelegate 's tableView(_:heightForRowAt:)

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableView.automaticDimension
        // return UITableViewAutomaticDimension for older than Swift 4.2
    }
    
  2. UITableViewDelegate 's tableView(_:estimatedHeightForRowAt:)

    func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableView.automaticDimension
        // return UITableViewAutomaticDimension for older than Swift 4.2
    }
    

Les étapes 1 et 2 vous permettent d’appliquer la taille automatique uniquement pour des lignes particulières. Pour appliquer à la UITableView entière, utilisez: 

tableView.rowHeight = UITableView.automaticDimension
tableView.estimatedRowHeight = UITableView.automaticDimension
// return UITableViewAutomaticDimension for older than Swift 4.2
0
Pranav Kasetti

J'avais trois éléments horizontaux et le plus à gauche avait une contrainte à gauche, celle du milieu en haut, en bas, à gauche et à droite. Le droit avait un droit, et à gauche au milieu. La solution consistait à ajouter des contraintes supplémentaires gauche et droite à l'élément du milieu (mon étiquette) qui étaient> = un certain nombre à la cellule.

0
user3739902

Pour que UITableViewAutomaticDimension fonctionne, vous devez vous assurer que les contraintes des 4 coins sont ajoutées à la vue d'ensemble. Dans la plupart des cas, cela fonctionne bien avec UILabel, mais je trouve parfois que UITextView fait l'affaire lorsque UILabel ne fonctionne pas bien à ce moment-là. Essayez donc de passer à UITextView et assurez-vous que Scrolling Enabled est décoché dans le storyboard, ou vous pouvez également le définir par programme.

0
Terry Tan

J'ai une nouvelle solution ... ça a fonctionné pour moi.

fondamentalement UITableViewAutomaticDimension renommé en UITableView.automaticDimension... J'espère..il wo

0

Assurez-vous que toutes les vues de la cellule sont contraintes à la vue Contenu et non à la cellule. 

Comme le dit Apple:

placez le contenu de la cellule de vue tableau dans la vue de contenu de la cellule. Pour définir la hauteur de la cellule, vous avez besoin d’une chaîne ininterrompue de contraintes et de vues (avec des hauteurs définies) pour remplir la zone située entre le bord supérieur et le bord inférieur de la vue de contenu.

0
fullMoon

cela fonctionnait bien pour moi dans iOS 11 et supérieur, alors que dans iOS 10 la solution consistait à ajouter

table.rowHeight = UITableView.automaticDimension
table.estimatedRowHeight = 200 // a number and not UITableView.automaticDimension

assurez-vous également que vous ajoutez "heightForRowAt" même si cela fonctionne dans iOS 11 et supérieur, il est nécessaire si vous prenez en charge iOS 10.

   func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableView.automaticDimension
    }
0
Bassant Ashraf