Je n'ai jamais travaillé avec autolayout contraintes auparavant. Je travaille sur une nouvelle petite application et j'ai remarqué que les vues de la carte NIB étaient automatiquement désactivées. Alors, j’ai pensé profiter de l’occasion pour travailler aveccela et essayer de comprendre où Apple va avec cela.
Premier défi:
J'ai besoin de redimensionner un MKMapView et j'aimerais l'animer à la nouvelle position. Si je le fais comme je suis habitué à:
[UIView animateWithDuration:1.2f
animations:^{
CGRect theFrame = worldView.frame;
CGRect newFrame = CGRectMake(theFrame.Origin.x, theFrame.Origin.y, theFrame.size.width, theFrame.size.height - 170);
worldView.frame = newFrame;
}];
... alors MKMapView reprendra sa hauteur d'origine à chaque mise à jour d'une vue parentale (dans mon cas, le titre d'un UISegmentedControl est en cours de mise à jour [myUISegmentedControl setTitle:newTitle forSegmentAtIndex:0]
).
Donc, ce que je thinkje veux faire, c’est modifier les contraintes de MKMapView de sorte qu’elles soient égales à la hauteur de la vue parent et qu’elles soient relatives au sommet du contrôle UISegmentedControl qu’elles étaitcouvrant: V:[MKMapView]-(16)-[UISegmentedControl]
Ce que je veux, c'est que la hauteur de MKMapView soit raccourcie afin que certains contrôles situés sous la vue de la carte soient révélés. Pour ce faire, je thinkj’ai besoin de changer la contrainte d’une vue fixe à une taille normale à une autre où le bas est contraint au sommet d’un UISegmentedControl ... et j’aimerais qu’elle s’anime à mesure que la vue se réduit à une nouvelle Taille.
Comment on s'y prend?
Éditez - cette animation est pasanimating bien que le bas de la vue passe à 170 immédiatement:
[UIView animateWithDuration:1.2f
animations:^{
self.nibMapViewConstraint.constant = -170;
}];
et la nibMapViewConstraint
est reliée dans IB à la contrainte d'espace vertical inférieure.
Après la mise à jour de votre contrainte:
[UIView animateWithDuration:0.5 animations:^{[self.view layoutIfNeeded];}];
Remplacez self.view
par une référence à la vue contenant.
Cela fonctionne pour moi (iOS7 et iOS8 +). Cliquez sur la contrainte de mise en page automatique que vous souhaitez ajuster (dans le générateur d'interface, par exemple la contrainte supérieure). Ensuite, faites-en un IBOutlet;
@property (strong, nonatomic) IBOutlet NSLayoutConstraint *topConstraint;
Animer vers le haut;
self.topConstraint.constant = -100;
[self.viewToAnimate setNeedsUpdateConstraints];
[UIView animateWithDuration:1.5 animations:^{
[self.viewToAnimate layoutIfNeeded];
}];
Retour au lieu d'origine
self.topConstraint.constant = 0;
[self.viewToAnimate setNeedsUpdateConstraints];
[UIView animateWithDuration:1.5 animations:^{
[self.viewToAnimate layoutIfNeeded];
}];
Apple a lui-même un très bon tutoriel qui explique comment utiliser une animation avec autolayout . Suivez ce lien link puis recherchez la vidéo intitulée "Mise en page automatique par exemple" et la dernière partie concerne l'utilisation de l'animation.
J'ai fait cette petite démo disponible . Il montre comment les contraintes de mise en page automatique peuvent être modifiées et animées dans un exemple très simple. Il suffit de regarder le DemoViewController.m .
La plupart des gens utilisent autolayout pour mettre en forme des éléments sur leurs vues et modifier les contraintes de mise en page pour créer des animations.
Un moyen simple de le faire sans beaucoup de code consiste à créer UIView que vous souhaitez animer dans Storyboard, puis à créer un UIView masqué à l'endroit où vous souhaitez que UIView se termine. Vous pouvez utiliser la prévisualisation dans xcode pour vous assurer que les deux UIViews sont là où vous le souhaitez. Après cela, cachez la fin de UIView et échangez les contraintes de présentation.
Si vous ne souhaitez pas l'écrire vous-même, il existe un fichier podfichier destiné à échanger des contraintes de mise en page, appelé SBP.
Il n'est pas nécessaire d'utiliser plus de IBOutlet reference
de la contrainte à la place de celle-ci. Vous pouvez directement utiliser la contrainte access
ou update
déjà appliquée, soit appliquée par Programmatically
, soit à partir de Interface Builder
sur toute vue utilisant la bibliothèque KVConstraintExtensionsMaster
. Cette bibliothèque gère également le comportement Cumulative
de NSLayoutConstraint
.
Pour ajouter une contrainte de hauteur sur containerView
CGFloat height = 200;
[self.containerView applyHeightConstrain:height];
Pour mettre à jour la contrainte de hauteur de containerView avec une animation
[self.containerView accessAppliedConstraintByAttribute:NSLayoutAttributeHeight completion:^(NSLayoutConstraint *expectedConstraint){
if (expectedConstraint) {
expectedConstraint.constant = 100;
/* for the animation */
[self.containerView updateModifyConstraintsWithAnimation:NULL];
}
}];