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];
It's a little rough around the edges, but here's what I did using block animations. The following flips the view, centers it and goes fullscreen:
I'm assuming you just want to change the image view's image while you flip and scale it. Following code flips the image view using default animation, scales it to the other view's frame and sets the image:
if you wish to show the A view as your tiny floating view again with some other image you can just set it's frame and image without the animation block in AnimationDidStopSelector method which you can set
where tinyRect is the floating A view's original frame.
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 ;-)
}
Checkout this svn repository:
This does flip two views.
Try something like this. As long as A's frame isn't fullscreen to start with then the animation should just flip A. When you add a subview to a view in a flip transition then it is added to the back of that view, so view A's frame is the one you want to modify.
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
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.