我想在视图的两个状态之间制作动画。比如说,我有一个带标签的视图,当我更改标签的文本时,动画会将更改呈现为页面翻转。
现在,您可以使用[UIView setAnimationTransition:forView:cache:]
:
- (IBAction)nextPage {
[UIView beginAnimation:nil context:nil];
[UIView setAnimationDuration:1];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:pageView cache:NO];
label.text = @"page 2";
[UIView commitAnimations];
}
- (IBAction)previousPage {
[UIView beginAnimation:nil context:nil];
[UIView setAnimationDuration:1];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlDown forView:pageView cache:NO];
label.text = @"page 1";
[UIView commitAnimations];
}
...但是你不能使用你自己的自定义动画,你会坚持使用内置的动画(它们很好但是它们不适合我的需要)。
所以另一个选择是在视图的图层中添加CAAnimation
:
- (IBAction)nextPage {
CAAnimation *animation = [self animationWithDuration:1 forward:NO];
[pageView.layer addAnimation:animation forKey:@"pageTransition"];
label.text = @"page 2";
}
- (IBAction)previousPage {
CAAnimation *animation = [self animationWithDuration:1 forward:YES];
[pageView.layer addAnimation:animation forKey:@"pageTransition"];
label.text = @"page 1";
}
然后您可以自由设置Core Animation允许您执行的任何动画。如果我定义CATransition
动画,例如kCATransitionReveal
,则效果很好:“页面2”状态下的视图在“页面1”状态下显示为滑出时。
- (CAAnimation *)animationWithDuration:(float)duration forward:(BOOL)forward {
CATransition *animation = [CATransition animation];
[animation setType:kCATransitionReveal];
[animation setSubtype:forward?kCATransitionFromLeft:kCATransitionFromRight];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]];
animation.duration = duration;
return animation;
}
但是当我将动画定义为例如CABasicAnimation
时,只能看到一个视图状态。
- (CAAnimation *)animationWithDuration:(float)duration forward:(BOOL)forward {
CATransform3D transform = CATransform3DIdentity;
transform.m34 = 1.0 / -1000;
transform = CATransform3DRotate(transform, M_PI, 0.0f, 1.0f, 0.0f);
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform"];
if(forward) {
animation.fromValue = [NSValue valueWithCATransform3D:transform];
} else {
animation.toValue = [NSValue valueWithCATransform3D:transform];
}
animation.duration = duration;
return animation;
}
相反,我希望“页面1”状态中的视图在动画结束时保持可见,而“页面2”状态中的视图进入框架,就像它使用过渡动画一样。
当然,我总是可以弄乱复制视图并让一个看起来像一个兄弟视图,同时我为最前面的一个制作动画并在完成后从superview中删除它...但是必须有一个更直接的方法来实现这一点相当简单的动画效果,而不会弄乱视图。
可能有什么东西告诉这个层,但后来我不知道是什么,那就是我需要你帮助的地方,伙计们:)
谢谢!
答案 0 :(得分:1)
我最近在控制器中的子视图之间进行了自定义幻灯片转换。我的方法是获取视图输出和视图的位图,将它们添加到视图并为该视图设置动画。最后,您可以删除转换视图并显示视图。这是转换方法的片段:
-(void) transitionToView:(UIView *)viewIn lastView:(UIView *)viewOut slideRight:(BOOL)isRight {
UIGraphicsBeginImageContext(viewOut.frame.size);
UIImageView *bitmapOut = [[UIImageView alloc] initWithFrame: viewOut.frame];
[viewOut.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewOutImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
bitmapOut.image = viewOutImage;
UIImageView *bitmapIn = [[UIImageView alloc] initWithFrame: viewIn.frame ];
bitmapIn.frame = CGRectMake(isRight ? 320 : -320, bitmapIn.frame.origin.y, bitmapIn.frame.size.width, bitmapIn.frame.size.height);
UIGraphicsBeginImageContext(viewIn.frame.size);
[viewIn.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewInImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
bitmapIn.image = viewInImage;
[self.view addSubview:transitionContainer];
[transitionContainer addSubview:bitmapIn];
[transitionContainer addSubview:bitmapOut];
[self removeAllViews];
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:0.5f];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(swapViewsAtEndOfTransition:)];
transitionContainer.frame = CGRectMake(isRight ? -320 : 320, 0, 640, 411);
[UIView commitAnimations];
[bitmapOut release]; bitmapOut = nil;
[bitmapIn release]; bitmapIn = nil;}
然后,在swapViewsAtEndOfTransition选择器中,您可以相应地更新视图。
答案 1 :(得分:0)
好吧,您可以创建一个图层,将其内容设置为代表您的视图最终状态的图像,而不是将动画应用于此图层。动画完成后,您可以删除图层并切换视图状态。
我认为这比实例化整个观点更有效。
答案 2 :(得分:0)
岁月已过,但我想我找到了适合你的解决方案。只需使用kCATransitionPush
代替kCATransitionReveal
即可。像这样:
- (CAAnimation *)animationWithDuration:(float)duration forward:(BOOL)forward {
CATransition *animation = [CATransition animation];
[animation setType:kCATransitionPush];
[animation setSubtype:forward?kCATransitionFromLeft:kCATransitionFromRight];
[animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]];
animation.duration = duration;
return animation;
}