Vous rencontrez l'effet secondaire d'une nouvelle fonctionnalité fantastique dans les vues de table d'iOS8: les hauteurs de ligne automatiques.
Dans iOS 7, vous aviez soit des lignes de taille fixe (définies avec tableView.rowHeight
), soit vous écriviez du code pour calculer la hauteur de vos cellules et vous le renvoyiez tableView:heightForRowAtIndexPath
. L'écriture de code pour le calcul de la hauteur d'une cellule pourrait être assez complexe si vous aviez de nombreuses vues dans votre cellule et que vous aviez différentes hauteurs à prendre en compte pour différentes tailles de police. Ajoutez Dynamic Type et le processus était une douleur dans le cul.
Dans iOS 8, vous pouvez toujours faire ce qui précède, mais maintenant la hauteur des lignes peut être déterminée par iOS, à condition que vous ayez configuré le contenu de votre cellule à l'aide de la disposition automatique. C'est un énorme avantage pour les développeurs, car à mesure que la taille de police dynamique change ou que l'utilisateur modifie la taille du texte à l'aide des paramètres d'accessibilité, votre interface utilisateur peut s'adapter à la nouvelle taille. Cela signifie également que si vous avez un UILabel qui peut avoir plusieurs lignes de texte, votre cellule peut maintenant s'agrandir pour accueillir celles lorsque les cellules en ont besoin, et se rétrécir quand ce n'est pas le cas, donc il n'y a pas d'espace blanc inutile.
Le message d'avertissement que vous voyez vous indique qu'il n'y a pas assez de contraintes dans votre cellule pour que la mise en page automatique informe le tableau de la hauteur de la cellule.
Pour utiliser la hauteur de cellule dynamique, qui, avec les techniques déjà mentionnées par d'autres affiches, éliminera également ce message, vous devez vous assurer que votre cellule a des contraintes suffisantes pour lier les éléments de l'interface utilisateur en haut et en bas de la cellule. Si vous avez déjà utilisé la mise en page automatique, vous êtes probablement habitué à définir des contraintes Top + Leading, mais la hauteur de ligne dynamique nécessite également des contraintes de fond.
La passe de mise en page fonctionne comme ceci, qui se produit immédiatement avant qu'une cellule ne s'affiche à l'écran, de manière juste à temps:
Les dimensions du contenu avec des tailles intrinsèques sont calculées. Cela inclut les UILabels et UIImageViews, où leurs dimensions sont basées sur le texte ou les UIImages qu'ils contiennent, respectivement. Ces deux vues considéreront leur largeur comme étant connue (parce que vous avez défini des contraintes pour les bords arrière / avant, ou vous avez défini des largeurs explicites, ou vous avez utilisé des contraintes horizontales qui révèlent finalement une largeur d'un côté à l'autre). Disons qu'une étiquette a un paragraphe de texte ("nombre de lignes" est défini sur 0 donc il sera automatiquement enveloppé), il ne peut faire que 310 points de diamètre, il est donc déterminé qu'il a une hauteur de 120pt à la taille de police actuelle.
L'interface utilisateur est aménagée en fonction de vos contraintes de positionnement. Il existe une contrainte en bas de l'étiquette qui se connecte à la marge inférieure de la cellule. Étant donné que l'étiquette a atteint une hauteur de 120 points et qu'elle est liée au bas de la cellule par la contrainte, elle doit pousser la cellule "vers le bas" (augmentant la hauteur de la cellule) pour satisfaire la contrainte qui dit "bas de l'étiquette est toujours à une distance standard du bas de la cellule.
Le message d'erreur que vous avez signalé se produit si cette contrainte inférieure est manquante, auquel cas il n'y a rien pour "pousser" le bas de la cellule loin du haut de la cellule, qui est l'ambiguïté qui est signalée: avec rien pour pousser le bas de en haut, la cellule s'effondre. Mais la mise en page automatique le détecte également et revient à utiliser la hauteur de ligne standard.
Pour ce que ça vaut, et surtout pour avoir une réponse arrondie, si vous implémentez les hauteurs de ligne dynamiques basées sur la disposition automatique d'iOS 8, vous devez l'implémenter tableView:estimatedHeightForRowAtIndexPath:
. Cette méthode d'estimation peut utiliser des valeurs approximatives pour vos cellules et elle sera appelée lors du chargement initial de la vue tableau. Cela aide UIKit à dessiner des éléments tels que la barre de défilement, qui ne peut pas être dessinée à moins que le tableau ne sache combien de contenu il peut faire défiler, mais n'a pas besoin de tailles totalement précises, car il ne s'agit que d'une barre de défilement. Cela permet de différer le calcul de la hauteur de ligne réelle jusqu'au moment où la cellule est nécessaire, ce qui est moins gourmand en calcul et permet à votre UITableView d'être présenté plus rapidement.