web-dev-qa-db-fra.com

La hauteur de l'extension iOS8 Today utilisant uniquement la mise en page automatique donne des contraintes brisées

La documentation Apple suggère de définir la hauteur des extensions d'aujourd'hui à l'aide de la mise en page automatique.

Si un widget a du contenu supplémentaire à afficher, vous pouvez vous fier aux contraintes de disposition automatique pour ajuster la hauteur du widget selon les besoins. Si vous n'utilisez pas la disposition automatique, vous pouvez utiliser la propriété UIViewController PreferredContentSize pour spécifier la nouvelle hauteur du widget.

Cependant, chaque exemple et tutoriel que j'ai vu finit par utiliser preferredContentSize.

Toutes mes tentatives pour régler la hauteur via la mise en page automatique ont conduit à des avertissements de contraintes brisées.

Réglage de la hauteur via Autolayout

J'ai commencé avec un nouveau modèle xcode et un nouveau modèle d'extension aujourd'hui. La seule chose que j'ai ajoutée au TodayViewController.m était:

- (UIEdgeInsets)widgetMarginInsetsForProposedMarginInsets:(UIEdgeInsets)defaultMarginInsets {
    return UIEdgeInsetsMake(0, 0, 0, 0);
}

Remarque: je reçois toujours ce problème si j'utilise simplement les marges par défaut.

J'ai contraint la hauteur de l'étiquette, centré l'étiquette dans le conteneur et contraint la hauteur du conteneur à être la même que la hauteur de l'étiquette:

Constrained Height

Cela devrait conduire à une étiquette qui remplit le conteneur à la hauteur spécifiée sans conflits de contraintes. Au lieu de cela, j'obtiens un conflit de contraintes:

2014-09-28 10:27:39.254 TodayExtension[61090:2672196] 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:0x7f8b8b62c670 V:[UILabel:0x7f8b8b62d9b0'Hello World'(124)]>",
    "<NSLayoutConstraint:0x7f8b8b583020 UIView:0x7f8b8b62d6e0.height == UILabel:0x7f8b8b62d9b0'Hello World'.height>",
    "<NSLayoutConstraint:0x7f8b8b5888a0 'UIView-Encapsulated-Layout-Height' V:[UIView:0x7f8b8b62d6e0(667)]>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x7f8b8b62c670 V:[UILabel:0x7f8b8b62d9b0'Hello World'(124)]>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.

De la façon dont il brise les contraintes, il finit par ressembler à ce que je veux: Constrained Height View

Cependant, dans d'autres projets, il décide de briser d'autres contraintes et il ne semble pas correct. Remarque également: si j'essaie de modifier la priorité de la contrainte de hauteur, il bloque Xcode. C'est donc amusant.

Hauteur non contraignante

J'avais espéré que, comme la limitation de la hauteur ne fonctionnait pas, peut-être que si je ne limitais pas la hauteur du conteneur aux sous-vues, cela déterminerait peut-être la hauteur requise pour héberger les sous-vues et se régler correctement.

J'ai centré la sous-vue et contraint sa hauteur:i.imgur.com/PwLmhj9.png

Cela a conduit à une extension qui utilise toute la hauteur du centre de notification et ma vue correctement dimensionnée centrée verticalement:

i.imgur.com/kKXlocu.png

Si je ne centre pas, mais que je fixe l'espace vertical au guide de mise en page supérieur, j'obtiens la même chose, sauf que la sous-vue est fixée en haut (mais le conteneur est toujours énorme).

Ce qui donne?

Je sais que je pourrais simplement utiliser preferredContentSize, mais alors pourquoi Apple dit-il qu'il peut être défini à l'aide des contraintes de disposition automatique? Que fais-je de mal?

Les exemples que j'ai donnés sont évidemment artificiels. Je règle la hauteur de la vue, alors pourquoi ne pas simplement régler la hauteur du conteneur, non? Une partie du point de cela dans un projet réel serait de définir la hauteur du widget en fonction de la largeur en utilisant uniquement la mise en page automatique.

43
Ryan C.

Après quelques expérimentations, et suis tombé sur " qu'est-ce que NSLayoutConstraint" UIView-Encapsulated-Layout-Height "et comment devrais-je le forcer à recalculer proprement " J'ai déterminé que vous pouvez contourner ce problème en utilisant l'un ou l'autre " Height "&" Equal Heights "OR" Height "and Top and Bottom" Vertical Space "(comme suggéré par Guilherme Sprint ), puis en diminuant la" Priority " de la contrainte de hauteur à 999.

Height Constraint with Reduced Priority

Ce n'est pas la réponse que j'espérais, mais il spécifie la hauteur du conteneur via la disposition automatique de la sous-vue et évite tout avertissement concernant les cassés contraintes.

Ma supposition/hypothèse/conclusion entièrement non scientifique est qu'iOS examine correctement les contraintes de mise en page pour déterminer la hauteur de la vue du conteneur. Il ajoute ensuite une nouvelle contrainte qui est de la même hauteur que ce qu'elle vient de calculer, mais cela limite désormais la hauteur. Réduire la priorité sur la contrainte de hauteur spécifiée par le développeur d'origine signifie que la contrainte générée par le système l'emporte et aucun avertissement n'est généré (j'aimerais en savoir plus à ce sujet de la part de quelqu'un qui le sait).

36
Ryan C.

Vous devez définir 5 contraintes au total pour faire de l'extension Today la taille que vous voulez vraiment.

4 contraintes définiront la relation avec la superview:

  • Top Space
  • Espace inférieur
  • Espace leader
  • Espace de fuite

Soit dit en passant, vous devez accrocher ces contraintes aux marges de mise en page, comme Apple recommande pour l'affichage, et spécialement les extensions d'aujourd'hui.

La 5ème contrainte sera la Height pour la sous-vue. Cette contrainte, ainsi que les espaces supérieur et inférieur, définira la taille exacte de votre section dans l'onglet Aujourd'hui.

Xcode Today Extension Constraints

En expliquant simplement cela, la contrainte de hauteur définira une constante pour la sous-vue, et les contraintes supérieure et inférieure "colleront" la vue d'ensemble aux bords de la sous-vue.

Today Extension running

5
Gui Moura

La hauteur de l'étiquette ne permet pas de satisfaire en même temps ces contraintes:

  • Hauteur minimale de l'étiquette
  • Top Space to Superview
  • Espace inférieur à Superview

Vous pouvez le résoudre en supprimant la contrainte Bottom Space to Superview, et le système de mise en page automatique affectera l'espace inférieur à l'espace restant.

0
Freeman