Cellules de type dynamic et auto-dimensionnées avec table statique

J'ai une application typique maître-détail qui permet à l'user de parcourir une list déroulante d'objects, puis d'explorer en détail pour un object particulier avec une séquence de poussée. La list principale de défilement est un UITableView construit avec des cellules prototypes, et la scène détaillée est un UITableView statique avec un nombre fixe de sections et de cellules.

Je souhaite implémenter Dynamic Type et Auto-Sizing Cells dans mon application afin que l'user puisse modifier la taille de la police de base. Jusqu'à présent, j'ai réussi à créer des cellules auto-dimensionnables avec la list déroulante des cellules prototypes: en utilisant Auto Layout, en définissant le nombre de lignes de chaque label sur 0 et en définissant tableView.rowHeight = UITableViewAutomaticDimension , la hauteur de chaque cellule prototype augmente ou se rétrécit pour s'adapter à la taille du text à l'intérieur.

Mais je ne peux pas get le même effet dans ma vue de table statique. Que j'utilise des cellules personnalisées ou des types de cellules embeddeds, la police augmente / diminue, mais pas la hauteur de la cellule.

Donc, ma question est en fait deux questions: 1) est-il possible de mettre en œuvre des cellules auto-dimensionnement dans les vues de table statique, comme je l'ai fait avec mon prototype de vue de table? et 2) si la réponse à la première question est non, comment puis-je écrire du code qui mesurera la hauteur d'une label dans une cellule de vue de table statique et ajuster la hauteur de cellule de manière appropriée?

Je vous remercie!

Les vues de table statique renvoient la hauteur de ligne définie dans Interface Builder. tableView.rowHeight paramètre tableView.rowHeight semble être complètement ignoré. C'est apparemment un bug dans UIKit.

Pour corriger cela, remplacez simplement -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath et renvoyez UITableViewAutomaticDimension .

Ajoutez d'abord cette fonction dans votre class

 func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { return UITableViewAutomaticDimension } func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { return UITableViewAutomaticDimension } 

Deuxièmement, pour que le file UITableViewAutomaticDimension fonctionne, assurez-vous d'avoir ajouté toutes les contraintes gauche, droite, inférieure et supérieure relatives à la vue du conteneur de cellules. N'oubliez pas de mettre le numéro de ligne de l'label à zéro.

Comme il s'agit d'une table statique, vous ne pouvez pas déquiler les cellules, donc vous devrez leur créer des IBOutlets, je les conserverais dans un tableau comme ceci:

 @IBOutlet var cells: [UITableViewCell]! 

Ensuite, vous devrez implémenter heightForRowAtIndexPath et calculer la taille:

 var rowSizes: [Int: CGFloat] = [:] override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { return calculateHeightForCell(indexPath) } func calculateHeightForCell(indexPath: NSIndexPath) -> CGFloat { // check if we already calculated the height if let height = rowSizes[indexPath.row] { return height } // else, calculate it let cell = cells[indexPath.row] let size = cell.contentView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize) rowSizes[indexPath.row] = size.height return size.height } 

rowSizes agit comme un cache, il tiendra les hauteurs des rangs, de sorte qu'ils ne seront calculés qu'une seule fois. Lorsque vous changez la taille de la police, videz simplement rowSizes et actualisez la table pour qu'elle soit calculée à nouveau.

Je suis reconnaissant pour les réponses fournies à la question que j'ai publiée hier. Malheureusement (et probablement à cause de mon inexpérience en tant que programmeur iOS), je n'ai pas réussi à faire fonctionner l'approche systemLayoutSizeFittingSize (UILayoutFittingCompressedSize). Après quelques essais et erreurs, cependant, j'ai trouvé une méthode différente qui semble fonctionner:

 import UIKit class MasterTVC: UITableViewController { @IBOutlet weak var staticCustomCellLabel: UILabel! //viewDidLoad override func viewDidLoad() { super.viewDidLoad() self.tableView.estimatedRowHeight = 44.0 staticCustomCellLabel.text = "This is the text for the static custom cell label; This is the text for the static custom cell label; This is the text for the static custom cell label" //Register handleDynamicTypeChange in observer: self NSNotificationCenter.defaultCenter().addObserver(self, selector: "handleDynamicTypeChange:", name: UIContentSizeCategoryDidChangeNotification, object: nil) } //deinit deinit { NSNotificationCenter.defaultCenter().removeObserver(self) } //handleDynamicTypeChange //called when user changes text size in Settings > General > Accessibility > Larger Text //or Settings > Display & Brightness > Text Size func handleDynamicTypeChange(notification: NSNotification) { staticCustomCellLabel.font = UIFont.preferredFontForTextStyle(UIFontTextStyleBody) self.tableView.reloadData() } //tableView:heightForRowAtIndexPath override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { return UITableViewAutomaticDimension } } 

Du côté de Storyboard, l'installation commence avec un seul controller de vue de table avec les propriétés suivantes:

  • Classe: MasterTVC (ma class personnalisée);
  • désigné le controller de vue initial;
  • Contenu: Cellules statiques
  • Style: groupé
  • Sections: 1.

Section 1:

  • Lignes: 1.

Cellule de vue de table:

  • Style: Personnalisé (l'utilisation de Basic entraîne la disparition de l'label lors de la modification de la taille du text dans les parameters);
  • Contenant un UILabel.

Le UILabel est en outre configuré comme:

  • Font: Body (un style de type dynamic);
  • Lignes: 0;
  • Épinglé sur les quatre côtés aux bords supérieur, inférieur, gauche et droit de la vue de contenu (j'ai utilisé les contraintes respectives 8, 8, 15, 15);
  • avec un @IBOutlet dans le code de class personnalisé.

Cela a fonctionné pour moi la design pour iOS 9 dans Xcode 7 et Swift 2 avec Auto Layout activé. Ce qui est intéressant, c'est que si vous supprimez le code NSNotificationCenter utilisé pour répondre immédiatement aux changements de taille de text, le code des cellules auto-dimensionnées est essentiellement deux lignes: settingRowHeight dans viewDidLoad et returnnant UITableViewAutomaticDimension de tableView: heightForRowAtIndexPath.

Sur la base de ces résultats, je crois que les réponses à ma question initiale sont: 1) oui; et 2) voir 1.