我有两个观点“A”和“B”。在窗口中间浮动(它不是全屏)。 B,将取代A的视图是全屏。我想编写一个自定义过渡,翻转A以显示背面的B,但同时缩放翻转矩形,以便在翻转完成时,B为全屏。
我尝试使用transitionFromView提供的翻转过渡:toView:duration:options:completion,但我只能翻转整个屏幕,而不是用A的帧开始翻转,以B的帧结束。
我知道我可以对视图的图层进行类似3D的转换,但我不确定应该使用哪组动画API来完成此操作。我尝试过的一件事是在transitionWithView的动画块中修改视图的图层属性:duration:options:animations:completion:但这不起作用,因为它似乎只是为了尊重视图属性修改。
有人能指出我正确的方向吗?我非常感激。
更新:到目前为止,这是我的代码。您可以在此处看到有关其功能的视频:http://www.youtube.com/watch?v=-xNMD2fGRwg
CGRect frame = [[UIApplication easybookDelegate] rootViewController].view.bounds ;
float statusHeight = [UIApplication sharedApplication].statusBarFrame.size.height ;
frame.origin.y = statusHeight ;
frame.size.height -= statusHeight ;
self.view.frame = frame ; // self.view is view "B"
// Put the snapshot as thet topmost view of our view
UIImageView *imageView = [[UIImageView alloc] initWithImage:image] ; // image is a snapshot of view "A"
imageView.frame = self.view.bounds ;
[self.view addSubview:imageView] ;
[self.view bringSubviewToFront:imageView] ;
// Pre-transform our view (s=target/current, d=target-current)
CGAffineTransform transform = CGAffineTransformIdentity ;
// Translate our view
CGPoint center = CGPointMake(screenOrigin.x + (image.size.width/2.0), screenOrigin.y + (image.size.height/2.0)) ;
float dX = center.x - self.view.center.x ;
float dY = center.y - self.view.center.y ;
NSLog( @"dx: %f, dy: %f" , dX, dY ) ;
transform = CGAffineTransformTranslate(transform, dX, dY) ;
// Scale our view
float scaleWFactor = image.size.width / self.view.frame.size.width ;
float scaleHFactor = image.size.height / self.view.frame.size.height ;
transform = CGAffineTransformScale(transform,scaleWFactor, scaleHFactor) ;
self.view.transform = transform ;
[[[UIApplication easybookDelegate] rootViewController].view addSubview:self.view] ;
// Perform the animation later since implicit animations don't seem to work due to
// view "B" just being added above and hasn't had a chance to become visible. Right now
// this is just on a timer for debugging purposes. It'll probably be moved elsewhere, probably
// to view "B"'s -didMoveToSuperview
double delayInSeconds = 0.3;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[UIView transitionWithView:self.view duration:3 options:UIViewAnimationOptionTransitionFlipFromRight| UIViewAnimationOptionCurveEaseOut animations:^(void)
{
[imageView removeFromSuperview] ;
self.view.transform = CGAffineTransformIdentity ;
}
completion:^(BOOL finished){
[self.view removeFromSuperview] ;
[navController presentModalViewController:self animated:NO] ;
}] ;
});
[imageView release];
CGRect frame = [[UIApplication easybookDelegate] rootViewController].view.bounds ;
float statusHeight = [UIApplication sharedApplication].statusBarFrame.size.height ;
frame.origin.y = statusHeight ;
frame.size.height -= statusHeight ;
self.view.frame = frame ; // self.view is view "B"
// Put the snapshot as thet topmost view of our view
UIImageView *imageView = [[UIImageView alloc] initWithImage:image] ; // image is a snapshot of view "A"
imageView.frame = self.view.bounds ;
[self.view addSubview:imageView] ;
[self.view bringSubviewToFront:imageView] ;
// Pre-transform our view (s=target/current, d=target-current)
CGAffineTransform transform = CGAffineTransformIdentity ;
// Translate our view
CGPoint center = CGPointMake(screenOrigin.x + (image.size.width/2.0), screenOrigin.y + (image.size.height/2.0)) ;
float dX = center.x - self.view.center.x ;
float dY = center.y - self.view.center.y ;
NSLog( @"dx: %f, dy: %f" , dX, dY ) ;
transform = CGAffineTransformTranslate(transform, dX, dY) ;
// Scale our view
float scaleWFactor = image.size.width / self.view.frame.size.width ;
float scaleHFactor = image.size.height / self.view.frame.size.height ;
transform = CGAffineTransformScale(transform,scaleWFactor, scaleHFactor) ;
self.view.transform = transform ;
[[[UIApplication easybookDelegate] rootViewController].view addSubview:self.view] ;
// Perform the animation later since implicit animations don't seem to work due to
// view "B" just being added above and hasn't had a chance to become visible. Right now
// this is just on a timer for debugging purposes. It'll probably be moved elsewhere, probably
// to view "B"'s -didMoveToSuperview
double delayInSeconds = 0.3;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
[UIView transitionWithView:self.view duration:3 options:UIViewAnimationOptionTransitionFlipFromRight| UIViewAnimationOptionCurveEaseOut animations:^(void)
{
[imageView removeFromSuperview] ;
self.view.transform = CGAffineTransformIdentity ;
}
completion:^(BOOL finished){
[self.view removeFromSuperview] ;
[navController presentModalViewController:self animated:NO] ;
}] ;
});
[imageView release];
答案 0 :(得分:3)
我以前做过这个。以下是我如何做到这一点的要点:
捕获视图A的UIImage,并将其设置为视图B的图像视图的图像
UIGraphicsBeginImageContext(view.bounds.size);
[viewA.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
viewB.imageView.image = image;
设置视图B的变换(缩放和平移),使其缩小到视图A的大小,并且位于视图A在屏幕上的位置
[UIView setAnimationTransition: UIViewAnimationTransitionFlipFromLeft forView:ViewB
结果是一个看起来像View A的动画正在翻转和缩放以填充屏幕,View B作为对面。
答案 1 :(得分:1)
结帐此svn存储库:
http://boondoggle.atomicwang.org/lemurflip/
这会翻转两个视图。
答案 2 :(得分:1)
这是我为你做的一个简单的例子:-)从它开始......尝试理解它......阅读文档,然后你就可以做你想做的事了; - )
- (void)moveTable:(UITableView *)table toPoint:(CGPoint)point excursion:(CGFloat)excursion {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:0.5];
[table setCenter:point];
// scaling
CABasicAnimation *scalingAnimation = (CABasicAnimation *)[table.layer animationForKey:@"scaling"];
if (!scalingAnimation)
{
scalingAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
scalingAnimation.duration=0.5/2.0f;
scalingAnimation.autoreverses=YES;
scalingAnimation.removedOnCompletion = YES;
scalingAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
scalingAnimation.fromValue=[NSValue valueWithCATransform3D:CATransform3DMakeTranslation(0.0, 0.0, 0.0)];
scalingAnimation.toValue=[NSValue valueWithCATransform3D:CATransform3DMakeTranslation(excursion, 0.0, 0.0)];
}
[table.layer addAnimation:scalingAnimation forKey:@"scaling"];
[UIView commitAnimations];
}
答案 3 :(得分:0)
尝试这样的事情。只要A的帧不是全屏开始,那么动画应该只是翻转A.当您在翻转过渡中向视图添加子视图时,它会被添加到该视图的背面,因此视图A的帧是一个你想修改。
[UIView beginAnimations:@"flipopen" context:nil];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self cache:TRUE];
[a addSubview:b];
a.frame = b.frame;
[UIView commitAnimations];
答案 4 :(得分:0)
我假设您只想在翻转和缩放图像时更改图像视图的图像。 下面的代码使用默认动画翻转图像视图,将其缩放到另一个视图的框架并设置图像:
[UIView beginAnimations:nil context:nil];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.imageViewA cache:NO];
[UIView setAnimationDuration:2];
[UIView setAnimationDelegate:self];
[UIView setAnimationDidStopSelector:@selector(animationFinished:)];
self.imageViewA.frame = self.imageViewB.frame;
self.imageViewA.image = self.imageViewB.image;
[UIView commitAnimations];
如果您希望再次使用其他图像将A视图显示为您的微小浮动视图,您可以在AnimationDidStopSelector方法中设置它的框架和图像,而无需动画块,您可以设置
-(void)animationFinished:(id)context
{
self.imageViewA.frame = tinyRect;
self.imageViewA.image = [UIImage imageNamed:@"a.jpg"];
}
其中tinyRect是浮动A视图的原始帧。
答案 5 :(得分:0)
边缘有点粗糙,但这就是我使用块动画做的事情。以下内容翻转视图,居中并全屏显示:
// the view on the other side of the card
UIView* redView = [[UIView alloc]initWithFrame:CGRectMake(0.0, 0.0, viewToFlip.frame.size.width, viewToFlip.frame.size.height)];
redView.backgroundColor = [UIColor redColor];
// add a green square to the red view so we have something else to look at
UIView* greenSquare = [[UIView alloc]initWithFrame:CGRectMake(10.0, 10.0, 20.0, 20.0)];
greenSquare.backgroundColor = [UIColor greenColor];
[redView addSubview:greenSquare];
// the flip animation
[UIView animateWithDuration:0.25
delay:0.0
options:UIViewAnimationCurveLinear
animations:^{
// rotate 90 degrees
[viewToFlip.layer setTransform: CATransform3DRotate(viewToFlip.layer.transform, -M_PI/2, 0.0, 1.0, 0.0)];
}
completion:^(BOOL finished){
// now that we're 90 degrees, swap one view for the other
// but if we add it now, the view will be backwards, so flip the original view back
[viewToFlip.layer setTransform: CATransform3DRotate(viewToFlip.layer.transform, M_PI, 0.0, 1.0, 0.0)];
[viewToFlip addSubview:redView];
// now let's continue our rotation
[UIView animateWithDuration:0.25
delay:0.0
options:UIViewAnimationCurveLinear
animations:^{
// rotate the last 90 degrees
[viewToFlip.layer setTransform: CATransform3DRotate(viewToFlip.layer.transform, -M_PI/2, 0.0, 1.0, 0.0)];
}
completion:^(BOOL finished){
[UIView animateWithDuration:0.25
delay:0.0
options:UIViewAnimationCurveLinear
animations:^{
// animate the views to the center of the screen and adjust their bounds to fill up the screen
[viewToFlip setCenter:CGPointMake(self.view.center.x, self.view.center.y)];
[viewToFlip setBounds:CGRectMake(0.0, 0.0, self.view.frame.size.width, self.view.frame.size.height)];
[redView setCenter:CGPointMake(self.view.center.x, self.view.center.y)];
[redView setBounds:CGRectMake(0.0, 0.0, self.view.frame.size.width, self.view.frame.size.height)];
}
completion:nil];
}];
}];