I have two views "A" and "B". A floats in the middle of the window (it's not full screen). B, the view which will replace A, is full screen. I'd like to write a custom transition that flips A to reveal B on the back side, but simultaneously scales the flipping rectangle so that when the flip is finished, B is full screen.
I've tried using the flip transitions available with transitionFromView:toView:duration:options:completion, but I can only get it to flip the entire screen instead of starting the flip with A's frame and ending with B's frame.
I know I can do 3D-like transforms to the view's layers, but I'm not sure which set of animation APIs I should use to accomplish this. One thing I tried is to modify the view's layer properties in the animations block of transitionWithView:duration:options:animations:completion: but that didn't work as it only seems to honor view property modifications.
Can someone point me in the right direction? I'd much appreciate it.
UPDATE: Here is my code thus far for this effect. You can see a video of what it does here: 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];
I've done this before. Here's the gist of how I did it:
Capture a UIImage of View A, and set it as the image of View B's image view
UIGraphicsBeginImageContext(view.bounds.size);
[viewA.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
viewB.imageView.image = image;
Set View B's transform (scale and translation) so that it is shrunk to the size of View A and is positioned where View A is on the screen
[UIView setAnimationTransition: UIViewAnimationTransitionFlipFromLeft forView:ViewB
The result is an animation that looks like View A is flipping over and zooming to fill the screen with View B as the opposite side.
Checkout this svn repository:
http://boondoggle.atomicwang.org/lemurflip/
This does flip two views.
This is an easy example that i made for you :-) Start with it... Try to understand it... Read Documentation and then you will be able to do what you want ;-)
- (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];
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With