iOS8 - les contraintes suggèrent de manière ambiguë une hauteur de zéro

100

Quelqu'un at-il une idée de comment déboguer cela?

Avertissement une seule fois: détection d'un cas où les contraintes suggèrent de manière ambiguë une hauteur de zéro pour la vue du contenu d'une cellule de vue table. Nous envisageons l'effondrement involontaire et utilisons à la place une hauteur standard.

Les rangées ont une hauteur fixe définie par

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

Et tout constraintssemble être heureux ...

Chris
la source

Réponses:

129

Forcer une hauteur de retour et une hauteur estimée ont fait disparaître l'avertissement dans mon cas.

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

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

Une autre solution où vous n'avez pas besoin des deux remplacements est simplement de les utiliser self.tableView.rowHeight = 44;dans votre loadViewméthode ou init.

FBronner
la source
1
J'ai plusieurs lignes de type dans la section et une seule d'entre elles a une hauteur dynamique. alors ça ne marche pas
Raj Aggrawal
Si nous définissons la hauteur par défaut dans xib / storyboard, nous n'avons pas à implémenter ces méthodes.
Satyam
77

Ce qui peut également être fait, c'est ajouter des contraintes verticales du haut et du bas de la vue du contenu. Cela rendra la mise en page automatique heureuse (car il sait maintenant calculer lui-même la hauteur de la cellule).

MonsieurDart
la source
2
Cela a fonctionné pour moi. J'ai parcouru toutes les cellules du conteneur et je me suis assuré qu'au moins une sous-vue avait à la fois une contrainte «espace supérieur vers conteneur» et une contrainte «espace inférieur vers conteneur».
Rog182
7
C'est la bonne réponse pour iOS 8 lors de l'utilisation de cellules de vue de tableau à taille automatique.
tsafrir le
1
Voulez-vous dire des contraintes d'éléments à l'intérieur de la vue de contenu vers le haut et le bas de la vue de contenu?
Zack Shapiro
J'ai essayé cela mais je reçois toujours un avertissement de contrainte contradictoire.
Shirish Kumar
2
Assurez-vous que vous ajoutez la contrainte supérieure et inférieure à la vue du contenu de la cellule, et non à la cellule elle-même. Si vous ajoutez une contrainte à la cellule, le code fonctionnera toujours mais tentera d'utiliser une hauteur de 0.
frin
26

Si vous utilisez des contraintes autoLayout et UITableViewAutomaticDimension, cette erreur n'est pas un problème erroné à ignorer en remplaçant votre hauteur dans le code. Cela signifie que la détermination automatique de la hauteur de cellule ne fonctionne pas car vous ne disposez pas des contraintes verticales nécessaires.

Si vous êtes comme moi et que vous obtenez cette erreur et que vous avez besoin d'aide pour identifier la cellule qui a généré l'erreur, vous pouvez ajouter la ligne suivante juste avant le retour de votre méthode 'heightforRowAtIndexPath'.

NSLog(@"Section %ld Row %ld", (long)[indexPath section], (long)[indexPath row]);

Cela imprimera une longue liste de sections et de lignes, mais l'erreur apparaîtra immédiatement après la cellule particulière à l'origine de l'erreur, et vous pourrez rapidement identifier la cellule à l'origine du problème et corriger vos contraintes en conséquence. Ceci est particulièrement utile pour les cellules statiques. Remplacer la hauteur par un nombre entré manuellement fonctionnera si vous n'utilisez pas la mise en page automatique et les hauteurs de cellule automatiques, mais désactivera essentiellement ces fonctionnalités, ce qui est une très mauvaise solution si vous essayez d'utiliser quelque chose.

Si vous n'utilisiez pas auparavant la méthode 'heightForRowAtIndexPath' mais que vous souhaitez déboguer cette erreur sans annuler votre paramètre UITableViewAutomaticDimension, ajoutez simplement ceci à votre code:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    NSLog(@"Section %ld Row %ld", (long)[indexPath section], (long)[indexPath row]);
    return UITableViewAutomaticDimension;
}
user2898617
la source
Merci beaucoup. Cela m'a beaucoup aidé. Au début, j'ai pensé que ce problème était lié à une autre cellule de vue de tableau. Après le débogage, il s'est avéré que ce problème était avec un autre.
akozin le
J'aimerais faire cela, mais les longues sections et lignes ne sont pas identifiées. Pourriez-vous clarifier ce que cela devrait être dans Swift?
DrWhat
9

Il semble y avoir un bogue dans XCode 6.1 qui provoque ce problème si vous utilisez la mise en page automatique et que vous ne spécifiez pas de valeur pour la hauteur de ligne pour chaque cellule de vue de tableau, mais à la place, vous laissez la valeur «par défaut». Le simple fait de cocher la case "Personnalisé" à côté de la hauteur de ligne, pour chaque cellule, fait disparaître l'avertissement.

ltm
la source
2
Si vous utilisez des cellules auto-dimensionnées, vous devez laisser la hauteur de ligne définie sur "par défaut".
phatmann
1
Cela a résolu l'avertissement. Mais je crois qu'il n'apparaît que lors de l' utilisation des cellules statiques dans TableView
MontiRabbit
1
@phatmann Ce problème n'apparaît que pour les cellules statiques. Par conséquent, les cellules ne doivent pas être auto-dimensionnées.
ltm
@ltm les cellules auto-dimensionnantes pourraient-elles ne pas être utiles, dans les cellules statiques, si l'utilisateur a peut-être agrandi le texte? (Vous savez, sous accessibilité dans les paramètres de l'iPhone)
Byron Coetsee
Je pense que ce n'est pas un bug, ça peut être un problème avec les contraintes verticales, ils doivent décrire complètement la hauteur de la cellule, pour les tables vues avec dimension automatique au moins.
juanjo
3

Oui, vous obtenez toutes les contraintes «heureuses» même dans le cas où vous n'avez que des contraintes horizontales pour les éléments de la cellule de vue tableau. J'ai eu le même problème. Vous devez également ajouter des contraintes verticales. Ce faisant, cet avertissement disparaîtra.

Juraj Antas
la source
3

Les contraintes peuvent être heureuses pour la mise en page, mais pas pour la hauteur automatique des lignes. Une mise en page heureuse signifierait que le contenu peut être mis en page sans ambiguïté. Cela satisferait les vérifications dans Interface Builder.

Une bonne disposition pour la hauteur de ligne automatique signifierait qu'en plus de ce qui précède, vous incluez également des contraintes au bas de la cellule.

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

Woodster
la source
3

J'ai utilisé la hauteur de ligne 43 (ou <> 44) dans l'inspecteur de taille de vue tableau et l'erreur a disparu. En utilisant 44, j'obtiens l'erreur. Xcode version 6.0.1.

- Cette réponse a été supprimée par un modérateur, ne le faites pas, cela résout le problème. Cela résout le problème pour moi et peut le faire pour d'autres aussi. Alors pourriez-vous être si gentil de ne pas le supprimer à nouveau.

teho
la source
2

Je n'ai pas pu supprimer l'avertissement, mais pour que les contraintes fonctionnent, j'ai défini la propriété, nouveau sur iOS8, tableview estimatedRowHeightsur la hauteur fixe et la heightForRowAtIndexPathmise en œuvre supprimée .

amir
la source
S'il n'a pas supprimé l'avertissement, c'est le système qui compense la contrainte manquante et définit la hauteur de ligne == sur la propriété cell.rowHeight. L'avertissement concerne une propriété de guérison automatique, si elle a été réparée automatiquement, cela signifie que le problème était-il non?
Pedro Borges
2

Si vous recevez cet avertissement, c'est probablement parce que vous utilisez la mise en page automatique et que vos cellules n'ont aucune contrainte à l'intérieur.

Vous devez soit arrêter d'utiliser la disposition automatique, soit implémenter des contraintes qui définissent sans ambiguïté la hauteur des cellules.

Vous pouvez désactiver la mise en page automatique dans le générateur d'interface en décochant l'option "Utiliser la mise en page automatique" dans l'inspecteur de fichiers sur la droite.

Si vous choisissez d'utiliser la disposition automatique et que la hauteur de vos cellules est fixe, la mise en œuvre des contraintes appropriées devrait être facile. Ajoutez simplement des contraintes de hauteur pour les sous-vues de la vue de contenu de la cellule et implémentez des contraintes d'espace vertical entre les sous-vues et entre les sous-vues et la vue de contenu. Par exemple, si votre cellule contient une étiquette, cela fonctionnerait:

Contraintes verticales

  1. Contrainte d'espace vertical entre le haut de la vue de contenu et le haut de l'étiquette
  2. Contrainte de hauteur fixe de l'étiquette
  3. Contrainte d'espace vertical entre le bas de l'étiquette et le bas de la vue de contenu

Contraintes horizontales

  1. Contrainte d'espace horizontal entre le bord avant de la vue de contenu et le bord avant de l'étiquette
  2. Contrainte de largeur fixe de l'étiquette
  3. Contrainte d'espace horizontal entre le bord arrière de l'étiquette et le bord arrière de la vue de contenu
Wrightak
la source
J'utilise des contraintes, et elles semblent toutes heureuses, comme mentionné dans la question.
Chris
Ces contraintes concernent-elles les sous-vues de la vue de contenu de la cellule? À quoi ressemblent-ils? Est-il possible que vous ayez des cellules différentes? Si vous définissez les cellules pour avoir une hauteur fixe à l'aide des solutions de Frederic Bonner, les contraintes sont remplacées.
wrightak
1

Vous pouvez utiliser AutoLayout pour calculer la bonne hauteur pour vous. Voici un joli article sur la hauteur de cellule dynamique sur iOS 8: http://natashatherobot.com/ios-8-self-sizing-table-view-cells-with-dynamic-type/

ricardopereira
la source
J'aurais aimé que ce soit aussi simple. L'ajout de ces deux lignes n'a malheureusement pas résolu mon problème de dimensionnement automatique
Zack Shapiro
1

Dans Swift, forcer une hauteur de retour a résolu mon problème:

override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    if(indexPath.row == 0){
       return CGFloat(131.0)
    }else if(indexPath.row == 8){
       return CGFloat(97.0)
    }else{
       return CGFloat(44.0)
    }
}
Roi-sorcier
la source
1

Pour un correctif standard de tourbière, pas de contraintes, pas d'estimation des hauteurs ou de sur-ingénierie du problème. J'ai créé un projet par défaut, câblé la vue de la table mais j'ai oublié de placer le délégué de hauteur dans le contrôleur de vue . Pour simplement faire disparaître cet avertissement, vous en avez besoin.

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

Dans le contrôleur de vue de votre table.

latenitecoder
la source
1

J'utilisais un mapView à l'intérieur de uitableviewcell. J'ai changé la hauteur de la vue de la carte à 1/3 de la taille de l'écran de l'appareil. J'ai eu la même erreur. J'ai corrigé l'erreur en ajoutant des contraintes manquantes à la vue du contenu de uitableviewcell.

1) Effacez les contraintes contentView.

2) Définissez Réinitialiser sur les constantes suggérées sur contentView.

entrez la description de l'image ici

3) Ajouter les contraintes manquantes - le cas échéant

4) Nous nous assurons que la vue du contenu a toutes les contraintes requises. entrez la description de l'image ici

AG
la source
0

Dans mon cas, c'est parce que je conçois la cellule avec xib et que j'oublie d'ajouter ce fichier xib à la cible.

Après avoir ajouté ce fichier xib à la cible, le problème a disparu

onmyway133
la source
0

Alors que les réponses sur cette page traitant de l'ajout de contraintes de hauteur ou du retour manuel de rowHeights comme 44 dans heightForRowAtIndexPath font disparaître l'avertissement, elles sont superflues car il s'agit d'un bogue dans Xcode visible au moins dans la version 6.3.2 (6D2105).

Si vous définissez un point d'arrêt dans viewDidLoad, vous verrez que self.tableView.rowHeight = -1 (UITableViewAutomaticDimension) même si vous spécifiez une hauteur de ligne de 44 dans le storyboard. En effet, Apple suppose à tort que vous souhaitez des hauteurs de ligne dynamiques si vous laissez la hauteur de ligne à 44, car ils ne vous ont pas fourni d'indicateur pour spécifier votre préférence.

Voici quelques solutions possibles et leurs résultats:

  • Définissez la hauteur de ligne sur 43 ou 45 dans le storyboard (œuvres).

  • Renvoie manuellement une hauteur de 44 dans heightForRowAtIndexPath (fonctionne).

  • Ajoutez des contraintes de hauteur entre les éléments de UITableViewCell et son contentView (fonctionne).

Malheureusement, ces solutions vous obligent à modifier votre conception, à ajouter des contraintes inutiles ou à ajouter du code inutile pour contourner un bogue. J'ai essayé (ce que je pensais être) la solution la plus simple:

  • Définissez la hauteur de chaque UITableViewCell sur 44 (personnalisé) dans le storyboard (échoue).

Je voulais vraiment une solution de storyboard pure à cela, alors j'ai finalement essayé:

  • Ajoutez un attribut d'exécution défini par l'utilisateur à UITableView dans le storyboard et nommez UITableView avec une note sur la façon dont son rowHeight est défini afin que les futurs développeurs puissent le trouver: (fonctionne):

entrez la description de l'image ici

entrez la description de l'image ici

Ces bogues sont trop courants dans le développement iOS et obligent les développeurs à passer trop de temps à évaluer les ramifications de la façon dont leurs solutions affecteront la maintenabilité à long terme.

Étant donné que trouver une solution conceptuellement correcte qui est maintenable et ne semble pas obscurcie est si insaisissable, et en supposant qu'Apple corrigera le bogue et que 44 sera la hauteur de ligne par défaut dans un avenir prévisible, alors la contrainte ou définie par l'utilisateur Les solutions d'attributs d'exécution sont probablement les plus faciles à maintenir.

Zack Morris
la source
0

Il se passe deux choses importantes ici, je pense.

1) Il est très facile de fausser les contraintes si vous ctrl + glissez. Alors, vérifiez que vous l'avez fait correctement. Il est préférable d'utiliser le plateau sur le côté gauche de l'écran pour dessiner ces contraintes.

2) Au lieu de spécifier la valeur EstiméeRowHeight dans ViewDidLoad ou ailleurs, utilisez la méthode déléguée

override func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {}

Cela a résolu le problème tout de suite pour moi.

Greg
la source
Pourquoi utilisez-vous le remplacement?
FractalDoctor
0

J'ai également vu cette erreur lors de l'utilisation de storyboards universels ou de xibs. Si vous négligez de spécifier les contraintes appropriées pour la classe de taille Any x Any, j'ai vu cette erreur apparaître.

Apple semble avoir corrigé ce problème pour iOS9. L'erreur ne s'est produite que le 8.4 pour moi.

David Nix
la source
0

J'ai tourné en rond pendant des jours entre cette erreur et une autre erreur dans laquelle des contraintes étaient créées (aucune idée de l'endroit) qui entraient en conflit avec les contraintes que je voulais. Je l'ai même fait fonctionner dans un cas où chaque propriété visible était identique à l'autre. La seule solution que j'ai trouvée était d'aller atomique - créer un fichier entièrement nouveau avec xib et recommencer à reconnecter les sorties en copiant-collant l'ancien code. Ce n'est peut-être pas la meilleure solution, mais parfois, si le problème n'est pas visible, il n'y a rien d'autre à faire. Au moins, devenir atomique est un bon moyen de revoir ce qui se passe.

DrWhat
la source