J'avais un problème similaire et ce fil de discussion m'a beaucoup aidé à le résoudre.
La réponse d'erurainon m'a mis sur la bonne voie, mais j'aimerais proposer une réponse légèrement différente. Le code suggéré par erurainon n'a pas fonctionné pour moi, car j'avais toujours un saut au lieu d'une transition animée. Le lien fourni par cnotethegr8 m'a donné la réponse qui fonctionne :
Guide de mise en page automatique https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/AutoLayoutbyExample/AutoLayoutbyExample.html (jusqu'au bas de la page).
Quelques différences par rapport à la réponse d'erurainon :
- Appelez layoutIfNeeded sur la vue du conteneur avant l'appel à une méthode d'animation (et au lieu de setNeedsUpdateConstraints sur myView).
- Définissez la nouvelle contrainte dans le bloc d'animations.
- Appelez layoutIfNeeded sur la vue du conteneur dans la méthode animations (après avoir défini la contrainte), au lieu de myView.
Cela correspondra au modèle suggéré par Apple dans le lien ci-dessus.
Un exemple
Je voulais animer une vue particulière, en la fermant ou en l'agrandissant par un simple clic sur un bouton. Comme j'utilise autolayout et que je ne voulais pas coder en dur des dimensions (dans mon cas la hauteur) dans le code, j'ai décidé de capturer la hauteur dans viewDidLayoutSubviews. Vous devez utiliser cette méthode et non viewWillAppear lorsque vous utilisez l'autolayout. Comme viewDidLayoutSubviews peut être appelé plusieurs fois, j'ai utilisé un BOOL pour me faire connaître la première exécution de mon initialisation.
// Code snippets
@property (weak, nonatomic) IBOutlet UIView *topView; // Container for minimalView
@property (weak, nonatomic) IBOutlet UIView *minimalView; // View to animate
@property (nonatomic) CGFloat minimalViewFullHeight; // Original height of minimalView
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *minimalViewHeightConstraint;
@property (nonatomic) BOOL executedViewDidLayoutSubviews;
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
// First execution of viewDidLayoutSubviews?
if(!self.executedViewDidLayoutSubviews){
self.executedViewDidLayoutSubviews = YES;
// Record some original dimensions
self.minimalViewFullHeight = self.minimalView.bounds.size.height;
// Setup our initial view configuration & let system know that
// constraints need to be updated.
self.minimalViewHeightConstraint.constant = 0.0;
[self.minimalView setNeedsUpdateConstraints];
[self.topView layoutIfNeeded];
}
}
Redimensionner l'extrait d'action complet
// An action to close our minimal view and show our normal (full) view
- (IBAction)resizeFullAction:(UIButton *)sender {
[self.topView layoutIfNeeded];
[UIView transitionWithView:self.minimalView
duration:1.0
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{
self.minimalViewHeightConstraint.constant = 0.0;
// Following call to setNeedsUpdateConstraints may not be necessary
[self.minimalView setNeedsUpdateConstraints];
[self.topView layoutIfNeeded];
} completion:^(BOOL finished) {
;
}];
// Other code to show full view
// ...
}
Redimensionner un petit extrait d'action
// An action to open our minimal view and hide our normal (full) view
- (IBAction)resizeSmallAction:(UIButton *)sender {
[self.topView layoutIfNeeded];
[UIView transitionWithView:self.minimalView
duration:1.0
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{
self.minimalViewHeightConstraint.constant = self.minimalViewFullHeight;
[self.minimalView setNeedsUpdateConstraints];
[self.topView layoutIfNeeded];
} completion:^(BOOL finished) {
;
}];
// Other code to hide full view
// ...
}
Vous pouvez utiliser animateWithDuration au lieu de transitionWithView si vous le souhaitez.
J'espère que cela vous aidera.