Détection d'un cas où les contraintes suggèrent de manière ambiguë une hauteur de zéro

120

Après la mise à jour vers Xcode 6.1 beta 2 lorsque j'exécute mon application qui contient des cellules de vue de table, l'assistant de débogage dit:

Warning once only: Detected a case where constraints ambiguously suggest a height of zero for a tableview cell's content view. We're considering the collapse unintentional and using standard height instead.

Avant, lorsque j'utilisais Xcode 5 sur ce projet, j'obtenais quelques erreurs, mais celles-ci ont disparu depuis la mise à niveau. Je n'ai pas d'autres erreurs ou avertissements maintenant. J'ai déjà essayé d'ajuster les tailles de toutes les cellules de tableview et j'ai également essayé d'utiliser la hauteur standard mais j'obtiens toujours le même avertissement:

Warning once only: Detected a case where constraints ambiguously suggest a height of zero for a tableview cell's content view. We're considering the collapse unintentional and using standard height instead.

J'ai également lu tous les sujets similaires à ce sujet, mais aucune de leurs solutions n'aide. Lorsque je teste l'application avec le simulateur, l'application fonctionne correctement, sauf que les images qui sont censées se trouver dans les cellules tableView ne sont pas là.

David E
la source
2
J'obtiens la même erreur pour la cellule de vue de collection. Ce que je fais pour ça. Aucune suggestion.
python
Peut-être que vous devriez vérifier si vous avez déjà ajouté le fichier xib à la cible stackoverflow.com/a/26870331/1418457
onmyway133
Cela m'est arrivé sur iOS 8.1, mais plus sur iOS 8.4. Si vous avez spécifié la hauteur, je suppose que ce n'est qu'un bogue Xcode.
samwize

Réponses:

126

Jusqu'à présent, trois choses ont réussi à faire taire cet avertissement. Vous pouvez choisir le plus pratique pour vous. Rien de joli cependant.

  • Pour configurer la hauteur de cellule par défaut dans viewDidLoad

    self.tableView.rowHeight = 44;
  • Accédez au storyboard et changez la hauteur de ligne de votre vue de table en quelque chose de différent de 44.

  • Pour implémenter la méthode déléguée de tableview heightForRowAtIndexPath

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        return 44;
    }

Bizarre.

Viktor Kucera
la source
J'ai également essayé d'utiliser votre méthode mais je dois ajouter un @property pour rowHeight mais je ne connais pas le type d'objet correct à utiliser
David E
Je n'ai peut-être pas reçu votre note, mais rowHeight est une propriété de UITableView. Connectez simplement votre table à une prise et c'est tout.
Viktor Kucera
4
En effet, si vous conservez la valeur 44 pt dans IB, il considérera que vous souhaitez utiliser des cellules à dimensionnement automatique. stackoverflow.com/questions/25888126/… (mais, oui, c'est un comportement étrange en effet)
Guillaume Algis
Donc, apparemment, j'avais deux méthodes viewDidLoad et j'ai mis self.tableView.rowHeight = 44;la mauvaise. L'erreur est partie! merci
David E
Merci Guillaume Algis d'avoir clarifié cela. C'est toujours très effrayant.
Viktor Kucera
216

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:

  1. 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.

  2. 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.

Woodster
la source
3
Ceci est une excellente explication de la raison fondamentale de cet avertissement. Merci beaucoup pour votre temps, Woodster!
Golden Thumb
4
Comme ce que Woodster a dit, j'ai raté la partie .Bottom des contraintes. Une fois ajouté, mon problème a été résolu.
Golden Thumb
Après avoir essayé près de 20 choses, c'est la seule qui a fonctionné!
Julio Rodrigues
Cet homme l'a cloué! Il mérite un vote favorable et cela doit être la réponse acceptée. +1
caraïbes
1
Voir cette réponse stackoverflow.com/a/29565073/4080860 afin de déterminer quelle cellule manque de contraintes.
hhanesand
11

J'ai eu ce problème après avoir créé une personnalisation UITableViewCellet ajouté mes sous-vues à la cellule au lieu de la sienne contentView.

ABakerSmith
la source
10

Pour résoudre ce problème sans méthode de programmation, ajustez la hauteur de ligne de la vue de tableau dans l'inspecteur de taille à partir du storyboard.

entrez la description de l'image ici

Anconia
la source
La meilleure solution pour moi car utilise les trucs du storyboard au lieu des lignes de code.
zyc
6

Il s'agit d'un problème de mise en page automatique. Assurez-vous que vos sous-vues ont toutes les contraintes. Pour moi, la contrainte inférieure manquait pour l'étiquette de titre dans la cellule. Quand j'ai ajouté cela, l'avertissement a disparu et tout est apparu parfaitement.

Alok
la source
Je ne sais pas pourquoi cela a été rejeté, car c'est une réponse parfaitement bonne. Voir ici pour obtenir de l'aide sur la détermination de la cellule qui rencontre des problèmes de présentation stackoverflow.com/a/29565073/4080860
hhanesand
5

Activez simplement les cellules de vue de tableau à taille automatique

   tableView.estimatedRowHeight = 85.0
   tableView.rowHeight = UITableViewAutomaticDimension

Et assurez- vous que vous avez ajouté des contraintes de tous les côtés de UITableViewCellAS-

entrez la description de l'image ici

Jack
la source
En fait, l'avertissement a disparu lorsque j'ai désactivé les cellules de vue de table auto-dimensionnées.
turingtested le
@turingtested, vous devez activer la cellule tableview auto-dimensionnée pour fournir une assistance sur divers appareils.
Jack le
D'accord, mais veuillez lire la question initiale. Ce que je voulais dire, c'est que votre solution suggérée n'a pas fonctionné, du moins pas pour moi.
turingtesté
FYI UITableViewAutomaticDimensiona été renommé enUITableView.automaticDimension
atineoSE
5

Si vous utilisez une cellule statique ou une cellule dynamique, ajoutez simplement une hauteur de ligne à la vue du tableau dans le tableau de l'inspecteur et décochez la case automatique à droite de la hauteur de ligne, c'est que vous cesserez de recevoir cet avertissement.entrez la description de l'image ici

Amit Verma
la source
J'ai trouvé le contraire plus efficace: définir une hauteur estimée explicite et laisser la hauteur de ligne elle-même être automatique.
NRitH
4

J'ai reçu cet avertissement aujourd'hui. Voici ce qui l'a fait disparaître pour moi (dans le constructeur d'interface)

1.Définissez le champ de hauteur de ligne pour la vue de table sur une valeur autre que 44 2 Définissez le champ de hauteur de ligne pour la cellule tableView sur une valeur autre que 44

Je n'ai pas eu à modifier le code

humblePilgrim
la source
3

Dans mon cas, je construisais la cellule par programme et continuais à recevoir cette erreur.

J'ajoutais les sous - vues et les contraintes dans la UITableViewCellde » initméthode comme ceci:

addSubview(rankingLabel)
addConstraints(cellConstraints)

J'ai résolu le problème en les ajoutant aux cellules à la contentViewplace:

contentView.addSubview(rankingLabel)
contentView.addConstraints(cellConstraints)
gohnjanotis
la source
1
Ajoutez toujours des sous-vues au contentView, pas UITableViewCelldirectement.
dinesharjani
3

Définissez la hauteur de ligne estimée sur zéro et l'avertissement disparaît:

entrez la description de l'image ici

TruMan1
la source
Le vrai problème est une contrainte manquante quelque part. Vous entrez probablement quelque chose verticalement au lieu de définir des contraintes haut / bas
TruMan1
1

J'ai moi aussi vécu cet avertissement en passant à Xcode 6 GM. Je ne recevais l'avertissement que lorsque j'ai fait pivoter l'appareil dans sa position d'origine.

J'utilise des UITableViewCells personnalisées. La vue de la table du storyboard est définie sur ma taille personnalisée (100,0 dans mon cas). Bien que les cellules du tableau s'affichent correctement comme dans les versions précédentes, je n'ai pas aimé le message d'avertissement.

En plus des idées ci-dessus, j'ai ajouté ceci

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return 100.0;
}

L'écran rend ... répond à la rotation et plus de messages d'avertissement.

DannyJi
la source
J'ai donc essayé d'utiliser votre méthode en utilisant la ligne que vous m'avez donnée mais j'ai toujours la même erreur. Je n'ai pas non plus utilisé la rotation dans mon application.
David E
1

Dans xcode 6.0.1, j'avais supprimé ces avertissements en spécifiant la hauteur de ligne en utilisant:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    return 44.0;
}
Fantini
la source
1

Si vous avez créé une cellule personnalisée tableViewCell pour tableView, assurez-vous que vous avez donné à la fois des contraintes inférieures et supérieures à vos cellules, vous pouvez également recevoir ce message si vos sous-vues à l'intérieur des cellules personnalisées sont alignées au centre Y, ce qui ne ferait pas apparaître de message d'erreur mais qui gâcherait avec l'identification de la hauteur de la ligne pour la vue de la table à son tour, comme dans l'image que j'ai jointe, ici nous avons des contraintes en haut et en bas

Lorsque vous créez une cellule personnalisée pour tableView, vous devez une hauteur de ligne spécifique ou des contraintes de haut et de bas pour les sous-vues de votre cellule personnalisée à l'intérieur de la cellule (par exemple, une étiquette dans une cellule personnalisée comme dans l'image ci-dessous)

Mais si cela ne fonctionne pas, vous pouvez essayer de définir la hauteur de ligne pour votre cellule au lieu d'être automatique comme dans cette image

Mais assurez-vous que si vous désactivez cette coche automatique, vous devez ajuster la taille de votre ligne pour les modifications par programme qui auraient pu être effectuées automatiquement

fosse monstre
la source
0

Dans le storyboard, définissez le cell Row heightchamp avec la même valeur que Row heightdans tableView(les deux avec la même valeur ont fonctionné pour moi).

Si vous ajoutez une heightForRowAtIndexPathfonction à votre code, cela peut induire un problème de performances car elle sera appelée pour chaque cellule, soyez donc prudent.

Daniel Gomez Rico
la source
0

Vous pouvez également voir ce message si vos seules contraintes sont définies pour aligner tous les éléments verticalement et que vous n'avez pas / souhaitez une hauteur spécifiée pour la cellule. Si vous définissez une contrainte haut / bas sur l'élément, l'avertissement disparaîtra.

Micah Montoya
la source
0

J'ai eu ce problème lorsque mes étiquettes et vues dans la table personnalisée ViewCell étaient limitées à customCell, pas à sa vue de contenu. Lorsque j'ai effacé les contraintes et les ai connectées aux cellules Affichage du contenu, le problème a été résolu.

Marija Zivkovic
la source
0

J'ai eu le même message d'erreur, assurez-vous que tous vos points de vente sont valides comme la vue table et les contraintes tableview

Gulz
la source
0

Si vous effectuez un calcul de hauteur dynamique,

  • vous devriez avoir tous les éléments liés les uns aux autres en termes de contraintes comme le haut et le bas.
  • vous devriez certainement avoir une contrainte de bas qui est liée à l'élément en bas de votre cellule
S. Mert
la source
0

J'ai également un problème similaire pour la cellule tableview personnalisée qui a une hauteur de ligne dynamique. La hauteur dynamique n'a pas été reflétée et a reçu le même avertissement dans la console. La solution consiste à ajouter des sous-vues à la cellule au lieu de contentView. BTW, j'ai créé des sous-vues par programme.

Srinivas G
la source
0

J'ai ce problème sur les TableViewCells où les contraintes sont définies lors de l'initialisation mais où le contenu de la cellule est chargé par la suite, cela signifie que le moteur de mise en page automatique ne peut pas déterminer la hauteur. Les autres solutions ici ne fonctionnent pas car j'ai besoin que la hauteur de la cellule soitUITableView.automaticDimension .

Je viens d'ajouter une contrainte supplémentaire à la cellule:

contentView.heightAnchor.constraint(equalToConstant: 44, priority: .defaultLow)
Léon
la source
0

J'ai reçu cet avertissement aujourd'hui Tout ce que j'ai fait, c'est simplement ajouter une ligne supplémentaire à mon code

tableView.rowHeight = 200;

ajoutez cette ligne de code dans le

func tableView(_ tableView: UITableView, numberOfRowsInSection section:Int) -> Int {
  ...
}

et le code final ressemble à

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  tableView.rowHeight = 200;
  ...
}

ce code augmentera la hauteur de la cellule de ligne du tableau à 200 la hauteur par défaut est 44

SudhakarH
la source
-1

J'ai la même erreur, en raison de cette ligne, cette erreur a été affichée.

self.layer.backgroundColor = UIColor (blanc: 1, alpha: 0,2) comme! CGColor

Je change juste la ligne comme suit pour corriger l'erreur

self.layer.backgroundColor = UIColor (blanc: 1, alpha: 0,2) .cgColor

Malik Hassnain
la source