2010-07-01 77 views
6

我想在视图的两种状态之间动画。比如说,我有一个带有标签的视图,当我更改标签的文本时,动画会呈现页面翻转时发生的变化。使用自定义动画在视图的两种状态之间动画

现在你当然可以做到这一点与[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"; 
} 

然后你可以随意设置任何动画核心动画让你做。如果我定义一个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”状态的视图进入帧,正是因为它与行为过渡动画。

当然,我总是可以在复制视图的同时让其中一个显示为兄弟视图,同时为最前面的视图制作动画并在完成时将其从超视图中移除...但是必须有更直接的方法才能实现这个相当简单的动画效果而不影响视图。

可能的事情告诉了一层,但我不知道是什么,而这也正是我需要你的帮助,球员:)

谢谢!

回答

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选择可以相应地更新视图。

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; 
}