I setup and customize the UINavigationController's
nav bar in viewWillAppear:
like I always do. I then have an NSTimer
firing in viewDidLoad
with a 0.6 time interval. This timer triggers my animation code.
I'm using Facebook's POP framework and all I want to do is use the following code to slightly change the layer's y position and bounce a little:
// Move object up
POPSpringAnimation *positionAnimation = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerPositionY];
positionAnimation.toValue = @(self.myView.frame.origin.y - 5);
positionAnimation.springBounciness = 20;
positionAnimation.velocity = @(2000);
[self.myView.layer pop_addAnimation:positionAnimation1 forKey:@"positionAnimation"];
For some reason, this always causes the view to go halfway underneath the UINavigationBar
. If I switch to the following code, the view will go to the correct position:
POPSpringAnimation *frameAnimation = [POPSpringAnimation animation];
frameAnimation.property = [POPAnimatableProperty propertyWithName:kPOPViewFrame];
frameAnimation.toValue = [NSValue valueWithCGRect:CGRectMake(12, 24, 91, 116)];
[self.myView.layer pop_addAnimation:secondFrameAnimation forKey:@"frameAnimation"];
The problem is, if I try to add any bounce to the frameAnimation
using the velocity
property, the app crashes and I get the following error:
'Invalid value', reason: '2000 should be of type CGRect'
If I take my positionAnimation
code and throw it into a new project that doesn't use a UINavigationController
with a navigation bar, everything works fine and the view animates to the correct y position. The only other difference too is that my current project is loading this view from a nib/xib
file, but everything is being done programmatically in the fresh project that works. I'm not really sure if that has anything to do with it.
So how can I use a nav controller with a navigation bar, but also successfully use the position animation?
EDIT:
I now have the animation working correctly, but still experiencing some very strange behavior. Here is the code that is successful at moving the view and not placing it halfway underneath the UINavigationBar
:
// Fade in
POPSpringAnimation *opacityAnimation = [POPSpringAnimation animation];
opacityAnimation.property = [POPAnimatableProperty propertyWithName:kPOPLayerOpacity];
opacityAnimation.toValue = @(1.0);
[self.design.layer pop_addAnimation:opacityAnimation forKey:@"opacityAnimation"];
// Move object up
POPSpringAnimation *positionAnimation1 = [POPSpringAnimation animationWithPropertyNamed:kPOPLayerPositionY];
positionAnimation1.toValue = @(self.design.frame.origin.y - 10);
positionAnimation1.springBounciness = 15;
positionAnimation1.velocity = @(2000);
[self.design.layer pop_addAnimation:positionAnimation1 forKey:@"positionAnimation"];
[positionAnimation1 setCompletionBlock:^(POPAnimation *anim, BOOL success) {
//
NSLog(@"design frame: %@", NSStringFromCGRect(self.design.frame));
}];
Here's what's weird though. When the above animation's completion block fires, the frame logs as this:
design frame: {{12, 36}, {91, 116}}
That's correct. However, if I alter the following line of the position animation and just switch in the y value of 36
, once again it ends up halfway underneath the UINavigationBar
:
positionAnimation1.toValue = @(36);
So why do I get a bad result when using the y value of 36, and why does it work if I use the y value of self.design.frame.origin.y - 10
, which ends up being 36 anyways?
Animating kPOPLayerPositionY
controls the y value of the position of the center of the layer, not the origin on the frame. The following should work:
positionAnimation1.toValue = @(36 + 116 * 0.5);
For the error with velocity that you mention earlier, this is because the number of components in the velocity parameter must match the number of components in the property being animated. So if you are animating a CGRect you need to pass a CGRect to velocity where each component is the velocity for the respective component.