web-dev-qa-db-fra.com

UITableViewAutomaticDimension ne fonctionne pas avant le défilement

Lorsque la vue Table est chargée pour la première fois, toutes les cellules visibles constituent la propriété estimationRowHeight. Lorsque je fais défiler l'écran vers le bas, les cellules sont automatiquement dimensionnées correctement et, lorsque je fais défiler vers le haut, les cellules initialement évaluées, RowHeight sont automatiquement dimensionnées correctement.

Une fois que les cellules sont automatiquement dimensionnées, elles ne semblent plus jamais redevenir le nombre estimé de RowHeight.

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
}

Vous avez des idées sur la manière dont les cellules doivent être automatiquement redimensionnées?

UPDATE: À partir de Xcode 7 beta 6, ce n'est plus un problème

24
jjatie

Je suis tombé sur le même problème et ai découvert que le accessoire cell.accessoryType gêne ce redimensionnement automatique quand ce n'est pas None

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

Accessory to "None" solved my issue

8
eule

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
Blank

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

Je fais également ce que @nosov suggère comme étant une bonne pratique, mais je n'ai pas vérifié si elles devaient être effectuées en tandem.

6
rob5408

il suffit de remplacer, comme ceci

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

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

5
Nosov Pavel

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

enter image description here

1
David Hernandez

Si vous définissez vos contraintes en fonction de la cellule elle-même (au lieu de l'affichage du contenu de la cellule), le tableau 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.

Toutefois, cela pose problème lorsque vos cellules prennent en charge la configuration avec/sans vue accessoire. Dans ce cas, la vue du contenu est redimensionnée en fonction de la vue des accessoires, et le résultat obtenu peut ne pas être celui attendu par l'utilisateur. Ainsi, dans ce cas, une solution définit 2 contraintes, une sur la cellule et une seconde avec une priorité inférieure sur la vue du contenu de la cellule.

1
Pablo A.

Pour moi, je n'ai que ce problème lorsque j'utilise une 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
MobileMon
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 vient du fait que le contenu de la cellule est chargé dans une autre fonction de délégué. Vous pouvez donc voir que les cellules sont automatiquement redimensionnées à la taille requise.

0
user4993619

Pour moi, ce qui a résolu le problème était la combinaison de @ [David Hernandez] answer .  enter image description here

Suppression de la sélection ci-dessus, et dans layoutSubviews de Cell, j'ai défini la couleur preferredMaxLayoutWidth comme ceci (remplacez 30 par l'espacement gauche-droit souhaité) 

-(void) layoutSubviews {
    [super layoutSubviews];
    self.textDescriptionLabel.preferredMaxLayoutWidth = self.frame.size.width - 30;
}
0
Kamran Khan

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

0
Miroslav Hrivik

Xcode 9.3, Swift 4.1 Ajout 

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

en plus de

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

a travaillé pour moi.

0
user3576382