dequeued UITableViewCell a une layout incorrecte jusqu'à ce qu'il défile (avec autolayout)

J'ai une sous-class UITableViewCell personnalisée à laquelle des contraintes de mise en forme automatique ont été appliquées dans Interface Builder. La cellule contient plusieurs vues, y compris un UITextField .

De manière pertinente, la taille de UITextField est contrainte de telle sorte qu'il existe un espacement horizontal par défaut entre la vue suivante et la vue suivante.

La cellule est instanciée comme suit:

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSSsortingng *CellIdentifier = @"ProgressCell"; ProgressCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath] cell.textField.text = @"Some ssortingng that is different for each cell"; return cell; } 

Lorsque la cellule apparaît pour la première fois, l' UITextField dépasse l'image correcte et apparaît derrière l' UIView à sa droite. Toutefois, lorsque je fais défiler l'écran hors cellule, mettre en pause, puis revenir en arrière, le text est tronqué correctement.

Un exemple est montré ci-dessous (à la deuxième édition).

J'ai essayé d'appeler [cell setNeedsLayout] et [cell setNeedsDisplay] pour la cellule dans cellForRowAtIndexPath , ainsi que de les effectuer après un timeout. Aucun n'est efficace.

Que fait le défilement de l'écran pour que la cellule apparaisse correctement, et comment puis-je répliquer cela ou résoudre le problème sous-jacent?

MODIFIER:

Appel

 [self.tableView reloadData]; [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationAutomatic]; 

afin de recharger la cellule, semble faire apparaître la layout correctement la première fois.

Cependant, il casse maintenant (occasionnellement) lors du défilement (c'est-à-dire, lors du défilement, les contraintes de disposition ne sont plus appliquées correctement).

Appeler [cell setNeedsLayout] dans cellForRowAtIndexPath semble ne pas résoudre ce problème.

EDIT2:

La cellule supérieure, comme montré ici , est apparue correctement (comme le fait la cellule du bas) jusqu'à ce que je fasse défiler l'écran. Il a disparu depuis.

Cela reflète le problème dès la première édition – c'est le deuxième rendu qui est le problème (me fait penser que cela pourrait avoir quelque chose à voir avec la réutilisation de la cellule?)

Si vous nommez une propriété sur une sous-class textLabel ou defaultTextLabel , IB ignore les contraintes que vous avez spécifiées et les remplace par celles par défaut, sans avertissement.

C'est le cas même sur les cellules conçues dans IB avec le style Custom, qui n'ont pas de propriétés textLabel ou detailTextLabel visibles.

Cela se produit également si vous ajoutez une propriété de type UIImageView sur une sous-class UITableViewCell et que vous la nommez imageView .

Conformément à ce UILabel lignes multiples UILabel GitHub , il s'agit d'un bug iOS persistant.

J'ai trouvé que dans iOS 9+, cette situation se produit principalement en mode d'édition, avec beaucoup d'imprévisibilité.

La solution de contournement suivante ne fonctionne que partiellement: elle nécessite de redessiner l' UITableView deux fois et ne couvre toujours pas tous les scénarios.

 override func viewDidLoad() { super.viewDidLoad() tableView.setNeedsLayout() tableView.layoutIfNeeded() tableView.reloadData() } 

Remarques:

  • L'utilisation de UITextView est une excellente alternative à plusieurs lignes UILabel , sans le bogue. UITextView ne présente aucune des autres bizarreries d' IULabel , comme les erreurs d'alignment ou le scintillement .
  • Il y a aussi une solution alternative sur SO-25947146 , qui n'a pas fonctionné pour moi mais mérite d'être mentionnée.
  • Semble se produire de manière évidente lorsque self.tableView.editing est true
  • L'utilisation de valeurs faibles pour tableView.estimatedRowHeight réduit l'occurrence
  • Démonstration du bogue sur SwiftArchitect / TableViewControllerRowHeightBug