UITableViewAutomaticDimension ne fonctionne pas jusqu'à défilement

Lorsque la vue de la Table est chargée pour la première fois, toutes les cellules visibles sont estimatedRowHeight. Comme je défile vers le bas, les cellules sont automatiquement dimensionnées correctement, et quand je défile vers le haut les cellules qui ont été initialement estimatedRowHeight sont automatiquement dimensionnées correctement.

Une fois que les cellules sont automatiquement dimensionnées,elles ne semblent jamais redevenir la hauteur estimée.

override func viewDidLoad() {
    super.viewDidLoad()
    self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: .Plain, target: nil, action: nil)
    self.tableView.estimatedRowHeight = 80.0
    self.tableView.rowHeight = UITableViewAutomaticDimension

    // Uncomment the following line to preserve selection between presentations
    // self.clearsSelectionOnViewWillAppear = false

    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem()
}

Et

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cellIdentifier = "Cell"
    let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as CustomTableViewCell

    // Configure the cell...
    let restaurant = restaurants[indexPath.row]
    cell.namelabel.text = restaurant.name
    cell.locationlabel.text = restaurant.location
    cell.typelabel.text = restaurant.type
    cell.thumbnailImageView.image = UIImage(named: restaurant.image)
    cell.thumbnailImageView.layer.cornerRadius = cell.thumbnailImageView.frame.size.width / 2
    cell.thumbnailImageView.clipsToBounds = true
    cell.accessoryType = restaurant.isVisited ? .Checkmark : .None

    return cell
}

Réflexions sur la façon d'avoir les cellules autoresize initialement?

Mise à jour: à partir de Xcode 7 beta 6 ce n'est plus un problème

24
demandé sur jjatie 2015-01-08 17:45:24

11 réponses

J'ai rencontré le même problème et j'ai découvert que l'accessoire cell.accessoryType mess avec ce redimensionnement automatique quand ce n'est pas None, donc cela semble être un bug dans Xcode pour le moment.

Mais comme @ Blankarsch l'a mentionné, appeler reloadSections(..) aide à résoudre ce problème si vous avez besoin d'un accessoire.

Accessoire à "aucun" résolu mon problème

8
répondu eule 2018-02-23 18:57:11

Appelez simplement "reloadSections" après le chargement de votre Table:

self.tableView.reloadSections(NSIndexSet(indexesInRange: NSMakeRange(0, self.tableView.numberOfSections())), withRowAnimation: .None)

Ou dans Swift 3:

let range = Range(uncheckedBounds: (lower: 0, upper: self.tableView.numberOfSections))
self.tableView.reloadSections(IndexSet(integersIn: range), with: .none)
26
répondu Blank 2017-01-17 11:47:20

Je pense que les réponses sur ici ont moins d'effets secondaires. Ajouter spécifiquement cell.layoutIfNeeded() dans tableView:cellForRowAtIndexPath:

Je fais aussi ce que @ nosov suggère comme une bonne pratique, mais je n'ai pas testé si elles doivent être faites en tandem.

6
répondu rob5408 2017-05-23 12:09:52

Juste remplacer estimatedHeightForRowAtIndexPath comme ceci

(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return UITableViewAutomaticDimension;
}

Et vérifiez vos contraintes autoLayout dans la vue CustomTableViewCell.

5
répondu Nosov Pavel 2015-04-06 07:16:16

Assurez-vous simplement que vos étiquettes n'ont pas de taille de contenu explicite définie dans Interface Builder. Ils doivent être automatiques comme la capture d'écran ci - dessous pour que la hauteur de ligne automatique fonctionne correctement sans avoir besoin de recharger les sections à l'avant.

entrez la description de l'image ici

1
répondu David Hernandez 2015-02-05 17:14:17

Si vous définissez vos contraintes en fonction de la cellule elle-même (au lieu de la vue du contenu de la cellule), la table ne peut pas obtenir la taille appropriée. Donc, pour résoudre ce problème, vos contraintes doivent être définies sur la vue de contenu.

Cependant, c'est un problème lorsque vos cellules prennent en charge les deux configurations avec/sans vue accessoire. Dans ce cas, la vue de contenu est redimensionnée en fonction de la vue accessoire, et le résultat peut ne pas être attendu par l'utilisateur. Donc, dans ce cas, une solution est de définir 2 contraintes, une à la cellule et une seconde avec une priorité inférieure à la vue de contenu de cellule.

1
répondu Pablo A. 2016-10-20 08:42:00
func tableView(_ tableView: UITableView, 
  cellForRowAt indexPath: IndexPath) -> UITableViewCell


- (UITableViewCell *)tableView:(UITableView *)tableView 
         cellForRowAtIndexPath:(NSIndexPath *)indexPath;

Dans la fonction, définissez la cellule avec le contenu préféré, afin que UITableViewAutomaticDimension fonctionne parfaitement.

Le problème est dû au fait que le contenu de la cellule est chargé dans une autre fonction de délégué, de sorte que vous pouvez voir que les cellules se redimensionnent automatiquement à la taille requise.

0
répondu 2016-09-30 13:43:28

Assurez-vous d'initialiser votre cellule dans tableView:cellForRowAt:. J'ai rencontré ce problème même avec Xcode 8 lorsque je définissais le contenu de la cellule dans tableView:willDisplay:forRowAt:

0
répondu Miroslav Hrivik 2017-07-26 12:06:16

Pour moi, je n'ai ce problème que lors de l'utilisation de la cellule willDisplay pour définir le texte de mes étiquettes

Si je définis le texte de mes étiquettes dans le chemin d'index cellForRowAt, tout va bien

0
répondu MobileMon 2017-08-14 14:57:32

Pour moi, ce qui a résolu c'était la combinaison de @ [David Hernandez] réponse. entrez la description de l'image ici

A supprimé la sélection d'en haut, et dans layoutSubviews de la cellule, j'ai défini le preferredMaxLayoutWidth comme ceci (changez 30 pour votre espacement gauche droit désiré)

-(void) layoutSubviews {
    [super layoutSubviews];
    self.textDescriptionLabel.preferredMaxLayoutWidth = self.frame.size.width - 30;
}
0
répondu Kamran Khan 2017-12-18 14:29:10

Xcode 9.3, Swift 4.1 ajouter

 func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}

En plus de

func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}

Travaillé pour moi.

0
répondu user3576382 2018-05-09 21:18:06