1011 votes

Comment animer la contrainte des changements?

Je suis à jour d'une ancienne application avec un AdBannerView et quand il n'y a pas d'annonce, il se glisse hors de l'écran. Quand il y a une annonce à ce qu'il glisse sur l'écran. Des trucs de base.

De style ancien, j'ai mis l'image dans un bloc d'animation. Nouveau style, j'ai un IBOutlet à la contrainte qui détermine la position Y, dans ce cas, c'est la distance à partir du bas de la superview, et de modifier la constante.

- (void)moveBannerOffScreen {
    [UIView animateWithDuration:5
             animations:^{
                          _addBannerDistanceFromBottomConstraint.constant = -32;
                     }];
    bannerIsVisible = FALSE;
}

- (void)moveBannerOnScreen {
    [UIView animateWithDuration:5
             animations:^{
                         _addBannerDistanceFromBottomConstraint.constant = 0;
             }];
    bannerIsVisible = TRUE;
}

Et la bannière se déplace, exactement comme prévu, mais pas d'animation.

Mise à JOUR: j'ai re-regardé WWDC12 vidéo "les Meilleures Pratiques pour la maîtrise de la Mise en page Automatique" qui couvre l'animation. Il explique comment mettre à jour les contraintes à l'aide de CoreAnimation.

enter image description hereenter image description here

J'ai essayé avec le code suivant, mais obtenir exactement les mêmes résultats.

- (void)moveBannerOffScreen {
    _addBannerDistanceFromBottomConstraint.constant = -32;
    [UIView animateWithDuration:2
                     animations:^{
                         [self.view setNeedsLayout];
                     }];
    bannerIsVisible = FALSE;
}

- (void)moveBannerOnScreen {
    _addBannerDistanceFromBottomConstraint.constant = 0;
    [UIView animateWithDuration:2
                     animations:^{
                         [self.view setNeedsLayout];
                     }];
    bannerIsVisible = TRUE;
}

Sur une note de côté, j'ai vérifié de nombreuses fois et ce qui est exécuté sur le thread principal.

1765voto

Gervasio Marchand Points 3789

Deux remarques importantes:

  1. Vous devez appeler layoutIfNeeded dans le bloc d'animation. Effectivement d'Apple recommande de vous appeler une fois avant le bloc d'animation pour s'assurer que tous en attendant la mise en page des opérations ont été achevées
  2. Vous avez besoin d'appeler explicitement à la vue parent (par exemple, self.view), pas à la vue enfant qui a des contraintes liées à elle. Cela permettra de mettre à jour toutes les contraintes vues, y compris l'animation d'autres points de vue qui pourraient être limitée à la vue de la modification de la contrainte (par exemple, la Vue B est fixée à la partie inférieure de Vue et que vous venez de modifier la Vue du haut de décalage et que vous souhaitez Afficher B pour animer avec elle)

Essayez ceci:

- (void)moveBannerOffScreen {
    [self.view layoutIfNeeded];

    _addBannerDistanceFromBottomConstraint.constant = -32;
    [UIView animateWithDuration:5
        animations:^{
            [self.view layoutIfNeeded]; // Called on parent view
        }];
    bannerIsVisible = FALSE;
}

- (void)moveBannerOnScreen { 
    [self.view layoutIfNeeded];

    _addBannerDistanceFromBottomConstraint.constant = 0;
    [UIView animateWithDuration:5
        animations:^{
            [self.view layoutIfNeeded]; // Called on parent view
        }];
    bannerIsVisible = TRUE;
}

116voto

J'apprécie la réponse, mais je pense qu'il serait bien de prendre un peu plus loin.

Le bloc de base de l'animation de la documentation

[containerView layoutIfNeeded]; // Ensures that all pending layout operations have been completed
[UIView animateWithDuration:1.0 animations:^{
     // Make all constraint changes here
     [containerView layoutIfNeeded]; // Forces the layout of the subtree animation block and then captures all of the frame changes
}];

mais vraiment c'est un scénario très simpliste. Que faire si je veux animer sous-vue des contraintes via l' updateConstraints méthode?

Un bloc d'animation qui appelle la sous-vues updateConstraints méthode

[self.view layoutIfNeeded];
[self.subView setNeedsUpdateConstraints];
[self.subView updateConstraintsIfNeeded];
[UIView animateWithDuration:1.0f delay:0.0f options:UIViewAnimationOptionLayoutSubviews animations:^{
    [self.view layoutIfNeeded];
} completion:nil];

Le updateConstraints méthode est substituée dans la sous-classe UIView et doit appeler super à la fin de la méthode.

- (void)updateConstraints
{
    // Update some constraints

    [super updateConstraints];
}

La mise en page automatique Guide laisse beaucoup à désirer, mais il vaut la peine de lire. Je suis moi-même à l'aide de cette partie d'un UISwitch qui permet de basculer d'une sous-vue avec une paire de UITextFields avec un simple et subtile de l'effondrement de l'animation (de 0,2 secondes). Les contraintes de la sous-vue sont gérés dans le UIView sous-classes updateConstraints méthodes décrites ci-dessus.

41voto

John Erck Points 1614
// Step 1, update your constraint
self.myOutletToConstraint.constant = 50; // New height (for example)

// Step 2, trigger animation
[UIView animateWithDuration:2.0 animations:^{

    // Step 3, call layoutIfNeeded on your animated view's parent
    [self.view layoutIfNeeded];
}];

3voto

D.D. Points 123

Il y a un article à ce sujet: http://weblog.invasivecode.com/post/42362079291/auto-layout-and-core-animation-auto-layout-was

Dans lequel, il a codé comme ceci:

- (void)handleTapFrom:(UIGestureRecognizer *)gesture {
    if (_isVisible) {
        _isVisible = NO;
        self.topConstraint.constant = -44.;    // 1
        [self.navbar setNeedsUpdateConstraints];  // 2
        [UIView animateWithDuration:.3 animations:^{
            [self.navbar layoutIfNeeded]; // 3
        }];
    } else {
        _isVisible = YES;
        self.topConstraint.constant = 0.;
        [self.navbar setNeedsUpdateConstraints];
        [UIView animateWithDuration:.3 animations:^{
            [self.navbar layoutIfNeeded];
        }];
    }
}

Espérons que cela aide.

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