Reputation: 1201
I am trying to animate sliding out one view from a window and simultaneous sliding in another. Like so:
Window
------------------
|----------------| ------------------
|| || | |
|| view || | view |
|| sliding out || | sliding in |
|----------------| ------------------
------------------
<--- <---
I'm using layer backed views, trying to use implicit animation and a CATransaction. What's happening is that the view sliding out animates, but the one sliding in, just jumps into place. Here's my code:
NSView *slidingInView = nil;
NSView *slidingOutView = nil;
if (currentState.primaryView != nextState.primaryView) {
// Slide in a primary view
[self.window.contentView addSubview:nextState.primaryView];
CGRect frame = nextState.primaryView.layer.frame;
frame.origin.x = slideFromRight ? frame.size.width : 0 - frame.size.width;
[nextState.primaryView.layer setPosition: frame.origin];
slidingInView = nextState.primaryView;
slidingOutView = currentState.primaryView;
}
[CATransaction begin];
[CATransaction setValue:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]
forKey:kCATransactionAnimationTimingFunction];
[CATransaction setAnimationDuration:1.0f];
[CATransaction setCompletionBlock:^{
[slidingOutView removeFromSuperview];
}];
// Slide in the new view
slidingInView.layer.position = CGPointMake(0.0f, 0.0f);
// if there is a view in place already, slide it out to the left.
if (slidingOutView != nil) {
CGRect frame = slidingOutView.layer.frame;
frame.origin = CGPointMake(slidingOutView.layer.frame.size.width, slidingOutView.layer.frame.origin.y);
if (slideRight)
frame.origin = CGPointMake(0-slidingOutView.layer.frame.size.width, slidingOutView.layer.frame.origin.y);
[slidingOutView.layer setPosition: frame.origin];
}
[CATransaction commit];
This is a complete mystery to me. Does anyone have a clue? My window's contentView has setWantsLayer: YES, as has all the views I'm sliding in.
Upvotes: 0
Views: 1898
Reputation: 56625
Implicit animations only work for standalone layers (layer that are not backing up a view).
You need to explicitly animate the layer (and change the property value since it doesn't happen by default). It would look something like
CABasicAnimation *slideIn = [CABasicAnimation animationWithKeyPath:@"position"];
[slideIn setToValue:[NSValue valueWithCGPoint:myNewEndPoint]];
[slideIn setFromValue:[NSValue valueWithCGPoint:[[slidingInView layer] position]]];
[[slidingInView layer] addAnimation:slideIn forKey:@"mySlideInAnimation"];
[[slidingInView layer] setPosition:myNewEndPoint];
Also: unless you have changed the anchor point, the position of the layer should be in the center (which means that setting it to (0,0) will make 3/4 of the layer appear off-screen
Upvotes: 2