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
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.
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)
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.
Juste remplacer estimatedHeightForRowAtIndexPath comme ceci
(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath {
return UITableViewAutomaticDimension;
}
Et vérifiez vos contraintes autoLayout dans la vue CustomTableViewCell.
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.
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.
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.
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:
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
Pour moi, ce qui a résolu c'était la combinaison de @ [David Hernandez] réponse.
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;
}
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.