Adam Carter
Adam Carter

Reputation: 4844

UIView animation happens in the wrong direction

For some reason my UIImageView animates to its start position, from its end position. I can’t work out why but have a feeling it’s something to do with using constraints (I use constraints on all UIViews throughout my app).

My animation should animate logoImageView off the top of the screen.

Here is my code:

NSLog(@"%@", NSStringFromCGPoint(self.logoImageView.center));

[self.logoImageView updateConstraintsIfNeeded];

[UIView animateWithDuration:3.0f
                 animations:^{
                     [self.logoImageView setCenter:CGPointMake(CGRectGetMidX(self.logoImageView.frame),
                                                               CGRectGetMaxY(self.view.frame) + CGRectGetHeight(self.logoImageView.frame))];

                     [self.logoImageView updateConstraintsIfNeeded];
                 } completion:^(BOOL finished) {
                     NSLog(@"%@", NSStringFromCGPoint(self.logoImageView.center));

                     [self performSegueWithIdentifier:@"Play" sender:nil];
                 }];

Here is my log of positions:

2014-09-05 18:08:56.673 Cups[2142:89629] {160, 111.5}
2014-09-05 18:09:01.250 Cups[2142:89629] {160, 645}

But the animation plays the other way round. Any ideas?

Upvotes: 0

Views: 1137

Answers (3)

Adam Carter
Adam Carter

Reputation: 4844

It turns out a CABasicAnimation running on the layer of the UIView was interrupting the UIView animation. Thanks for suggestions

Upvotes: 0

Aaron
Aaron

Reputation: 7145

This probably has something to do with the fact that you're calling -updateLayoutConstraints without actually updating constraints.

A better approach would be to animate the constraints rather than setting the position and frames of your views. A good trick to remember is that you can create outlets in your XIB to your constraints.

Let's assume you have an NSLayoutConstraint called logoImageViewTopConstraint set up as an IBOutlet in your view controller which sets the top of the logoImageView to it's superview's top layout guide. At design time set that constraint's constant to 100 or so (moving it down 100 points from the top of the view). Then with that constraint you could do something like this for your animation:

[self.view layoutIfNeeded];
self.logoImageViewTopConstraint.constant = 0;   // moves image view back to the top
[self.view setNeedsUpdateConstraints];    
[UIView animateWithDuration:0.8 delay:0.0 options:UIViewAnimationOptionCurveEaseOut animations:^{
    [self.view layoutIfNeeded];             // interpolates animation from changes to constraints
} completion:^(BOOL finished) {
    // done
}];

If you get it working just play with the constants of the constraints until you get the exact effect that you want.

Upvotes: 1

CSmith
CSmith

Reputation: 13458

What happens if you do this:

[UIView animateWithDuration:3.0f
                 animations:^
                 {
                     [self.logoImageView setCenter:CGPointMake(CGRectGetMidX(self.logoImageView.frame),
                                                           -(CGRectGetHeight(self.logoImageView.frame)/2)];

                 } completion:^(BOOL finished) 
                 {
                     [self performSegueWithIdentifier:@"Play" sender:nil];
                 }];
  1. animate to y center = -(logoHeight/2). This is "off the top of the screen" in iOS coordinates
  2. don't call updateConstraints in animation block

Upvotes: 0

Related Questions