290 votes

ce qui est NSLayoutConstraint « UIView-encapsulé-mise en page-Height » et comment faut-il moins forçant à recalculer proprement

J'ai un UITableView fonctionnant sous iOS8 Beta4 je suis en utilisant automatique de la hauteur de cellule à partir de contraintes dans un storyboard.

Un de mes cellules contient une seule UITextView et j'ai besoin d'elle pour se contracter et se dilater en fonction de l'entrée utilisateur - tapez pour réduire/agrandir le texte.

Je fais cela par l'ajout d'un moteur d'exécution de la contrainte à l'affichage de texte et de la modification de la constante de la contrainte en réponse à des événements de l'utilisateur:

-(void)collapse:(BOOL)collapse; {

    _collapsed = collapse;

    if(collapse)
            [_collapsedtextHeightConstraint setConstant: kCollapsedHeight]; // 70.0
        else
            [_collapsedtextHeightConstraint setConstant: [self idealCellHeightToShowFullText]];

    [self setNeedsUpdateConstraints];

}

Whenver le faire, je l'envelopper dans de la tableView mises à jour et l'ensemble de la tableView besoins updateConstraint:

[tableView beginUpdates];

[_briefCell collapse:!_showFullBriefText];

[tableView setNeedsUpdateConstraints];
// I have also tried 
// [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationTop];
// with exactly the same results.

[tableView endUpdates];

Quand je fais cela, mon cellulaire ne se développer (et de l'anime, tout en le faisant) mais je reçois des contraintes d'avertissement:

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 mycalculated hauteur des autres contraintes sur la UITextview de la mine à partir de Xcode/IB.

La dernière, c'est de me tracasser - je suppose qu' UIView-Encapsulated-Layout-Height est calculé à hauteur de la cellule quand il s'est rendu pour la première fois - (j'ai mis mon UITextView hauteur >= 70.0) howevcer il ne semble pas juste que cette dérivée contrainte puis annule une mise à jour de l'utilisateur cnstraint.

Pire encore, bien que la mise en page de code dit que c'est en essayant de me casser la hauteur de la contrainte, il n'a pas - il va à recalculer la hauteur de la cellule et tout attire comme je le voudrais.

Alors, qu'est-ce que NSLayoutConstraint "UIView-Encapsulé-Mise en page-Hauteur" (je suppose que c'est la taille calculée pour automatique de la cellule de dimensionnement) et comment dois-je le forcer à recalculer proprement?

311voto

Ortwin Gentz Points 15102

Essayez de diminuer la priorité de votre à 999. De cette façon le système fourni contrainte prévaut toujours.

73voto

Gold Thumb Points 135

J'ai un scénario similaire: une vue de la table avec une ligne de la cellule, dans lequel il ya quelques lignes de UILabel objets. Je suis de l'utilisation d'iOS 8 et de mise en page automatique.

Quand j'ai tourné, j'ai obtenu le mauvais système calculée à hauteur de ligne (43.5 est beaucoup moins que la hauteur réelle). Il ressemble:

"<NSLayoutConstraint:0x7bc2b2c0 'UIView-Encapsulated-Layout-Height' V:[UITableViewCellContentView:0x7bc37f30(43.5)]>"

Ce n'est pas juste un avertissement. La mise en page de mon tableau vue de la cellule est terrible tout le texte superposé sur une ligne de texte.

Ça m'étonne que la ligne suivante résout mon problème comme par magie(mise en page automatique se plaint de rien et je reçois ce que j'attends sur l'écran):

myTableView.estimatedRowHeight = 2.0 // any number but 2.0 is the smallest one that works

avec ou sans cette ligne:

myTableView.rowHeight = UITableViewAutomaticDimension // by itself this line only doesn't help fix my specific problem

34voto

Jeff Bowen Points 1306

J'ai été en mesure d'obtenir l'avertissement d'aller loin en spécifiant une priorité sur l'une des valeurs de la contrainte les messages d'avertissement, dit-il dû à la rupture (en-dessous de "Will attempt to recover by breaking constraint"). Il semble que tant que j'ai mis la priorité à quelque chose de plus grand que 49, l'avertissement disparaît.

Pour moi cela signifiait changer ma contrainte de l'avertissement dit-il tenté de briser:

@"V:|[contentLabel]-[quoteeLabel]|"

pour:

@"V:|-0@500-[contentLabel]-[quoteeLabel]|"

En fait, je peux ajouter une priorité à l'un quelconque des éléments de contrainte et il va fonctionner. Il ne semble pas à la matière. Mes cellules a la fin de la bonne hauteur et l'avertissement n'est pas affiché. Roger, pour votre exemple, essayez d'ajouter de l' @500 juste après l' 388 de la hauteur de la valeur de la contrainte (par exemple, 388@500).

Je ne suis pas entièrement sûr de savoir pourquoi cela fonctionne, mais j'ai fait une petite enquête. Dans le NSLayoutPriority enum, il semble que l' NSLayoutPriorityFittingSizeCompression niveau de priorité est - 50. La documentation de ce niveau de priorité, dit:

Lorsque vous envoyez un fittingSize message à vue, à la plus petite taille est assez grand pour le point de vue du contenu est calculée. C'est le niveau de priorité avec laquelle la vue veut être aussi petits que possible ce calcul. C'est assez faible. Il n'est généralement pas approprié pour faire une contrainte à cette priorité. Vous voulez être plus ou bas.

La documentation de référence fittingSize message se lit comme suit:

La taille minimale de la vue qui satisfait les contraintes qu'il détient. (lecture seule)

AppKit définit cette propriété à la meilleure taille disponible pour la vue, compte tenu de toutes les contraintes et de ses sous-vues tenir et satisfaire une préférence pour rendre la vue la plus petite possible. L' les valeurs de la taille de cette propriété ne sont jamais négatives.

Je n'ai pas creusé au-delà de cela, mais il ne semble pas faire sens que cela a quelque chose à voir avec l'endroit où se trouve le problème.

8voto

Austin Points 3222

Au lieu d’informer la vue table pour mettre à jour ses contraintes, essayer de recharger la cellule :

``est sans doute la hauteur de la table vue calculée pour la cellule pendant le chargement initial, basé sur les contraintes de la cellule à l’époque.

6voto

Cullen SUN Points 895

Une autre possibilité :

Si vous utilisez auto mise en page pour calculer la hauteur de la cellule (hauteur d’AffichageContenu, la plupart du temps comme ci-dessous), et si vous avez uitableview séparateur, vous devez ajouter la hauteur du séparateur, afin de revenir à la hauteur de cellule. Une fois que vous obtenez la bonne hauteur, vous n’aurez pas cet avertissement de mise en forme automatique.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X