J'ai un UITableView
fonctionnement sous iOS 8 et j'utilise des hauteurs de cellule automatiques à partir de contraintes dans un storyboard.
Une de mes cellules contient une seule UITextView
et j'en ai besoin pour se contracter et se développer en fonction de la saisie de l'utilisateur - appuyez sur pour réduire / développer le texte.
Je fais cela en ajoutant une contrainte d'exécution à la vue texte et en modifiant la constante de la contrainte en réponse aux événements utilisateur:
-(void)collapse:(BOOL)collapse; {
_collapsed = collapse;
if(collapse)
[_collapsedtextHeightConstraint setConstant: kCollapsedHeight]; // 70.0
else
[_collapsedtextHeightConstraint setConstant: [self idealCellHeightToShowFullText]];
[self setNeedsUpdateConstraints];
}
Chaque fois que je fais cela, je l'enveloppe dans les tableView
mises à jour et appelle [tableView setNeedsUpdateConstraints]
:
[tableView beginUpdates];
[_briefCell collapse:!_showFullBriefText];
[tableView setNeedsUpdateConstraints];
// I have also tried
// [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationTop];
// with exactly the same results.
[tableView endUpdates];
Lorsque je fais cela, ma cellule se développe (et s'anime en le faisant) mais j'obtiens un avertissement de contraintes:
2014-07-31 13:29:51.792 OneFlatEarth[5505:730175] Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)
(
"<NSLayoutConstraint:0x7f94dced2b60 V:[UITextView:0x7f94d9b2b200'Brief text: Lorem Ipsum i...'(388)]>",
"<NSLayoutConstraint:0x7f94dced2260 V:[UITextView:0x7f94d9b2b200'Brief text: Lorem Ipsum i...']-(15)-| (Names: '|':UITableViewCellContentView:0x7f94de5773a0 )>",
"<NSLayoutConstraint:0x7f94dced2350 V:|-(6)-[UITextView:0x7f94d9b2b200'Brief text: Lorem Ipsum i...'] (Names: '|':UITableViewCellContentView:0x7f94de5773a0 )>",
"<NSLayoutConstraint:0x7f94dced6480 'UIView-Encapsulated-Layout-Height' V:[UITableViewCellContentView:0x7f94de5773a0(91)]>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x7f94dced2b60 V:[UITextView:0x7f94d9b2b200'Brief text: Lorem Ipsum i...'(388)]>
388 est ma hauteur calculée, les autres contraintes sur la UITextView
mienne sont de Xcode / IB.
Le dernier me dérange - je suppose que UIView-Encapsulated-Layout-Height
c'est la hauteur calculée de la cellule lors de son premier rendu - (j'ai défini ma UITextView
hauteur sur> = 70,0) mais il ne semble pas juste que cette contrainte dérivée annule ensuite une utilisateur mis à jour cnstraint.
Pire encore, bien que le code de mise en page dise qu'il essaie de briser ma contrainte de hauteur, il ne le fait pas - il continue à recalculer la hauteur de la cellule et tout dessine comme je le voudrais.
Alors, quelle est NSLayoutConstraint
UIView-Encapsulated-Layout-Height
(je suppose que c'est la hauteur calculée pour le dimensionnement automatique des cellules) et comment devrais-je le forcer à recalculer proprement?
self.contentView.autoresizingMask = UIViewAutoresizingFlexibleHeight;
. Je pense que la définition initiale du masque de redimensionnement automatique empêche la dernière contrainte d'être ajoutée. J'ai trouvé cette solution ici: github.com/wordpress-mobile/WordPress-iOS/commit/…<rect key="frame" x="0.0" y="0.0" width="600" height="110"/>
dans sa définition, ce qui me fait croire qu'il s'agit d'un bogue IB . Au moins, le mien l'était de toute façon.Réponses:
Essayez de réduire la priorité de votre
_collapsedtextHeightConstraint
à 999. De cette façon, laUIView-Encapsulated-Layout-Height
contrainte fournie par le système est toujours prioritaire.Il est basé sur ce que vous retournez
-tableView:heightForRowAtIndexPath:
. Assurez-vous de renvoyer la bonne valeur et votre propre contrainte et celle générée doit être la même. La priorité inférieure pour votre propre contrainte n'est nécessaire que temporairement pour éviter les conflits lorsque les animations de réduction / expansion sont en cours.la source
UIView-Encapsulated-Layout-Height
contrainte est ajoutée par UITableView une fois les hauteurs déterminées. Je calcule la hauteur en fonctionsystemLayoutSizeFittingSize
de la contentView. Ici,UIView-Encapsulated-Layout-Height
ça n'a pas d'importance. Ensuite, la tableView définit explicitement contentSize à la valeur renvoyée parheightForRowAtIndexPath:
. Dans ce cas, il est correct de réduire la priorité de nos contraintes personnalisées car la contrainte tableView doit avoir priorité après le calcul des rowHeights.UIView-Encapsulated-Layout-Height
ça ne va pas si je ne baisse pas la priorité ...UIView-Encapsulated-Layout-Width
dans mon cas est tout simplement faux, mais il semble être préféré à mes contraintes explicites lors de l'exécution.J'ai un scénario similaire: une vue de table avec une cellule de ligne, dans laquelle il y a quelques lignes d'objets UILabel. J'utilise iOS 8 et la mise en page automatique.
Lorsque j'ai pivoté, j'ai obtenu la mauvaise hauteur de ligne calculée par le système (43,5 est beaucoup moins que la hauteur réelle). On dirait:
Ce n'est pas seulement un avertissement. La disposition de ma cellule de vue de table est terrible - tout le texte se chevauchait sur une seule ligne de texte.
Cela m'étonne que la ligne suivante "corrige" mon problème comme par magie (la mise en page automatique ne se plaint de rien et j'obtiens ce que j'attends à l'écran):
avec ou sans cette ligne:
la source
estimatedRowHeight
plus bascellForRowAtIndexPath
sera appelé le plus souvent au départ. la hauteur de la vue de table divisée par les temps estimés de RowHeight, pour être exact. Sur un iPad Pro 12 pouces, cela peut potentiellement être un nombre par milliers et marteler la source de données et entraîner un retard important.J'ai pu faire disparaître l'avertissement en spécifiant une priorité sur l'une des valeurs de la contrainte que les messages d'avertissement indiquent qu'il devait casser (ci-dessous
"Will attempt to recover by breaking constraint"
). Il semble que tant que je fixe la priorité à quelque chose de supérieur à49
, l'avertissement disparaît.Pour moi, cela signifiait changer ma contrainte, l'avertissement disait qu'il tentait de briser:
@"V:|[contentLabel]-[quoteeLabel]|"
à:
@"V:|-0@500-[contentLabel]-[quoteeLabel]|"
En fait, je peux ajouter une priorité à n'importe lequel des éléments de cette contrainte et cela fonctionnera. Peu importe lequel. Mes cellules finissent à la bonne hauteur et l'avertissement ne s'affiche pas. Roger, pour votre exemple, essayez d'ajouter
@500
juste après la388
contrainte de valeur de hauteur (par exemple388@500
).Je ne sais pas vraiment pourquoi cela fonctionne, mais j'ai fait un peu d'enquête. Dans l' énumération NSLayoutPriority , il semble que le
NSLayoutPriorityFittingSizeCompression
niveau de priorité soit50
. La documentation de ce niveau de priorité indique:La documentation du
fittingSize
message référencé se lit comme suit:Je n'ai pas creusé au-delà de cela, mais il semble logique que cela ait quelque chose à voir avec le problème.
la source
99,9% du temps, lorsque vous utilisez des cellules ou des en-têtes personnalisés, tous les conflits
UITableViews
se produisent lorsque la table se charge pour la première fois. Une fois chargé, vous ne verrez généralement plus le conflit.Cela se produit car la plupart des développeurs utilisent généralement une hauteur fixe ou une contrainte d'ancrage quelconque pour mettre en page un élément dans la cellule / en-tête. Le conflit se produit car lors du
UITableView
premier chargement / mise en page, il définit la hauteur de ses cellules à 0. Cela entre évidemment en conflit avec vos propres contraintes. Pour résoudre ce problème, définissez simplement les contraintes de hauteur fixes sur une priorité inférieure (.defaultHigh
). Lisez attentivement le message de la console et voyez quelle contrainte le système de disposition a décidé de briser. Habituellement, c'est celui qui a besoin de changer de priorité. Vous pouvez changer la priorité comme ceci:la source
J'ai pu résoudre cette erreur en supprimant une fausse
cell.layoutIfNeeded()
que j'avais dans montableView
decellForRowAt
méthode.la source
Au lieu d'indiquer à la vue de table de mettre à jour ses contraintes, essayez de recharger la cellule:
UIView-Encapsulated-Layout-Height
est probablement la hauteur que la vue de table a calculée pour la cellule pendant la charge initiale, en fonction des contraintes de la cellule à ce moment.la source
Une autre possibilité:
Si vous utilisez la disposition automatique pour calculer la hauteur de la cellule (hauteur de contentView, la plupart du temps comme ci-dessous), et si vous avez un séparateur uitableview, vous devez ajouter la hauteur du séparateur, afin de revenir à la hauteur de la cellule. Une fois que vous aurez la bonne hauteur, vous n'aurez plus cet avertissement de mise en page automatique.
la source
UITableViewAutomaticDimension
dansheightForRowAtIndexPath
Je reviens[sizingCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize] + 0.1
[sizingCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height + 0.1
Comme mentionné par Jesse dans le commentaire de la question, cela fonctionne pour moi:
Pour info, ce problème ne se produit pas dans iOS 10.
la source
J'ai eu cette erreur lors de l'utilisation de UITableViewAutomaticDimension et de la modification d'une contrainte de hauteur sur une vue à l'intérieur de la cellule.
J'ai finalement compris que cela était dû au fait que la valeur constante de la contrainte n'était pas arrondie à l'entier le plus proche.
la source
Le dimensionnement de la vue texte pour l'adapter à son contenu et la mise à jour de la constante de contrainte de hauteur à la hauteur résultante ont corrigé le
UIView-Encapsulated-Layout-Height
conflit de contraintes pour moi, par exemple:la source
Après avoir passé quelques heures à me gratter la tête avec ce bug, j'ai finalement trouvé une solution qui fonctionnait pour moi. mon principal problème était que j'avais plusieurs plumes enregistrées pour différents types de cellules, mais qu'un type de cellule en particulier était autorisé à avoir des tailles différentes (toutes les instances de cette cellule ne seront pas de la même taille). le problème est donc survenu lorsque la vue de table a tenté de retirer une cellule de ce type de la file d'attente et que sa hauteur était différente. Je l'ai résolu en mettant
self.contentView.autoresizingMask = UIViewAutoresizingFlexibleHeight; self.frame = CGRectMake(0, 0, self.frame.size.width, {correct height});
chaque fois que la cellule avait ses données pour calculer sa taille. Je pense que ça peut être
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
quelque chose comme
cell.contentView.autoresizingMask = UIViewAutoresizingFlexibleHeight; cell.frame = CGRectMake(0, 0, self.frame.size.width, {correct height});
J'espère que cela t'aides!
la source
TableView obtient la hauteur de la cellule à indexPath du délégué. puis récupérez la cellule de
cellForRowAtIndexPath
:si cell.contentView.height: 0 // <-> (UIView-Encapsulated-Layout-Height: 0 @ 1000) top (10 @ 1000) en conflit avec (UIView-Encapsulated-Layout-Height: 0 @ 1000),
en raison de leurs priorités sont égales à 1000. Nous devons définir la priorité supérieure sous
UIView-Encapsulated-Layout-Height
la priorité de.la source
Je recevais un message comme celui-ci:
J'utilise une coutume
UITableViewCell
avecUITableViewAutomaticDimension
pour la hauteur. Et j'ai également implémenté laestimatedHeightForRowAtIndex:
méthode.La contrainte qui me posait des problèmes ressemblait à ceci
Changer la contrainte en ceci résoudra le problème, mais comme une autre réponse, j'ai senti que ce n'était pas correct, car cela abaisse la priorité d'une contrainte que je veux être requise:
Cependant, ce que j'ai remarqué, c'est que si je supprime simplement la priorité, cela fonctionne également et je n'obtiens pas les journaux de contraintes de rupture:
C'est un peu un mystère quant à la différence entre
|-6-[title]-6-|
et|-[title-|
. Mais spécifier la taille n'est pas un problème pour moi et cela supprime les journaux, et je n'ai pas besoin de baisser la priorité de mes contraintes requises.la source
Définir cela
view.translatesAutoresizingMaskIntoConstraints = NO;
devrait résoudre ce problème.la source
J'ai eu un problème similaire avec une cellule de vue de collection.
Je l'ai résolu en abaissant la priorité de la dernière contrainte liée au bas de la cellule (la dernière de la chaîne du haut vers le bas de la vue - c'est finalement ce qui détermine sa hauteur) à 999.
La hauteur de la cellule était correcte et les avertissements ont disparu.
la source