Flip, Grow and Translate Animation

Check out this video at MLB At Bat. Basically, I just want to represent modalViewController using the UIModalPresentationFormSheet style and enlarge it from another view and then flip it. For example, when you click on a game on a scoreboard in an MLB application. Does anyone know how I can do this?

thanks

EDIT: my main view is almost the same setup as the MLB application. I use AQGridView and want the animation to AQGridView when the grid cell is pressed.

EDIT 2: I would also be open to drop the concept of a UIViewController and just use a simple UIView and then replicate the UIModalPresentationFormSheet style manually if that is easier.

EDIT 3: Well, forget to use the UIViewController to do this, since I have not received any answers, I assume this is not possible. My new question is how can I play the animation in a hosted video using only UIView ? Therefore, basically, the original representation should grow, move and flip everything at the same time.

EDIT 4: I think I have real animation, now my only problem is calculating the coordinates to feed into CATransform3DTranslate . My opinion should be animated pretty much the same as in the video. It should start from a different view and approach the center of the screen. Here, as I try to calculate the coordinates for the view that appears in the center:

 CGPoint detailInitialPoint = [gridView convertPoint:view.frame.origin toView:detailView.frame.origin]; CGPoint detailFinalPoint = detailView.frame.origin; 

gridView is a container view of my main view, which stores smaller grid elements. view is a specific mesh element from which we animate. And the detailView is the view that appears in the middle of the screen.

+8
ios objective-c cocoa-touch ipad core-animation
source share
5 answers

OK, I get it. Here is what I did:

 CGFloat duration = 0.8; /* //Detail View Animations */ CATransform3D initialDetailScale = CATransform3DMakeScale(view.frame.size.width/vc.view.frame.size.width, view.frame.size.height/vc.view.frame.size.height, 1.0); CATransform3D initialDetailTransform = CATransform3DRotate(initialDetailScale, -M_PI, 0.0, -1.0, 0.0); CATransform3D finalDetailScale = CATransform3DMakeScale(1.0, 1.0, 1.0); CATransform3D finalDetailTransform = CATransform3DRotate(finalDetailScale, 0.0, 0.0, -1.0, 0.0); NSMutableArray *detailAnimations = [NSMutableArray array]; CABasicAnimation *detailTransform = [CABasicAnimation animationWithKeyPath:@"transform"]; detailTransform.fromValue = [NSValue valueWithCATransform3D:initialDetailTransform]; detailTransform.toValue = [NSValue valueWithCATransform3D:finalDetailTransform]; detailTransform.duration = duration; [detailAnimations addObject:detailTransform]; CABasicAnimation *detailFadeIn = [CABasicAnimation animationWithKeyPath:@"opacity"]; detailFadeIn.fromValue = [NSNumber numberWithFloat:1.0]; detailFadeIn.toValue = [NSNumber numberWithFloat:1.0]; detailFadeIn.duration = duration/2; detailFadeIn.beginTime = duration/2; [detailAnimations addObject:detailFadeIn]; CABasicAnimation *detailMove = [CABasicAnimation animationWithKeyPath:@"position"]; detailMove.fromValue = [NSValue valueWithCGPoint:vc.view.layer.position]; detailMove.toValue = [NSValue valueWithCGPoint:self.view.layer.position]; detailMove.duration = duration; [detailAnimations addObject:detailMove]; CAAnimationGroup *detailGroup = [CAAnimationGroup animation]; [detailGroup setAnimations:detailAnimations]; [detailGroup setDuration:duration]; detailGroup.removedOnCompletion = NO; detailGroup.fillMode = kCAFillModeForwards; detailGroup.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; [vc.view.layer addAnimation:detailGroup forKey:@"anim"]; /* //Grid Item View Animations */ CATransform3D initialGridScale = CATransform3DMakeScale(1.0, 1.0, 1.0); CATransform3D initialGridTransform = CATransform3DRotate(initialGridScale, 0.0, 0.0, 1.0, 0.0); CATransform3D finalGridScale = CATransform3DMakeScale(vc.view.frame.size.width/view.frame.size.width, vc.view.frame.size.height/view.frame.size.height, 1.0); CATransform3D finalGridTransform = CATransform3DRotate(finalGridScale, M_PI, 0.0, 1.0, 0.0); NSMutableArray *gridAnimations = [NSMutableArray array]; CABasicAnimation *gridTransform = [CABasicAnimation animationWithKeyPath:@"transform"]; gridTransform.fromValue = [NSValue valueWithCATransform3D:initialGridTransform]; gridTransform.toValue = [NSValue valueWithCATransform3D:finalGridTransform]; gridTransform.duration = duration; [gridAnimations addObject:gridTransform]; CABasicAnimation *gridFadeOut = [CABasicAnimation animationWithKeyPath:@"opacity"]; gridFadeOut.fromValue = [NSNumber numberWithFloat:0.0]; gridFadeOut.toValue = [NSNumber numberWithFloat:0.0]; gridFadeOut.duration = duration/2; gridFadeOut.beginTime = duration/2; [gridAnimations addObject:gridFadeOut]; CABasicAnimation *gridMove = [CABasicAnimation animationWithKeyPath:@"position"]; gridMove.fromValue = [NSValue valueWithCGPoint:view.layer.position]; gridMove.toValue = [NSValue valueWithCGPoint:[self.view.layer convertPoint:self.view.layer.position toLayer:gridView.layer]]; gridMove.duration = duration; [gridAnimations addObject:gridMove]; CAAnimationGroup *gridGroup = [CAAnimationGroup animation]; [gridGroup setAnimations:gridAnimations]; gridGroup.duration = duration; gridGroup.fillMode = kCAFillModeForwards; gridGroup.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; gridGroup.removedOnCompletion = NO; [view.layer addAnimation:gridGroup forKey:@"anim"]; 

I am doing this with an element in an AQGridView . In my view code example, there is an instance of AQGridViewCell that I am animating. And vc.view is my detail of the UIViewController / UIView that I'm showing.

+1
source share

You can implement your own transition using the category in the UIViewControler.

UIViewController + ShowModalFromView.h

 #import <Foundation/Foundation.h> #import <QuartzCore/QuartzCore.h> @interface UIViewController (ShowModalFromView) - (void)presentModalViewController:(UIViewController *)modalViewController fromView:(UIView *)view; @end 

UIViewController + ShowModalFromView.m

 #import "UIViewController+ShowModalFromView.h" @implementation UIViewController (ShowModalFromView) - (void)presentModalViewController:(UIViewController *)modalViewController fromView:(UIView *)view { modalViewController.modalPresentationStyle = UIModalPresentationFormSheet; // Add the modal viewController but don't animate it. We will handle the animation manually [self presentModalViewController:modalViewController animated:NO]; // Remove the shadow. It causes weird artifacts while animating the view. CGColorRef originalShadowColor = modalViewController.view.superview.layer.shadowColor; modalViewController.view.superview.layer.shadowColor = [[UIColor clearColor] CGColor]; // Save the original size of the viewController view CGRect originalFrame = modalViewController.view.superview.frame; // Set the frame to the one of the view we want to animate from modalViewController.view.superview.frame = view.frame; // Begin animation [UIView animateWithDuration:1.0f animations:^{ // Set the original frame back modalViewController.view.superview.frame = originalFrame; } completion:^(BOOL finished) { // Set the original shadow color back after the animation has finished modalViewController.view.superview.layer.shadowColor = originalShadowColor; }]; } @end 

This can be easily changed to use any animated transition you want; for yours, you can use CA3DTransform. Hope this helps!

+6
source share

To flip, grow and translate an animation, you can use the following code:

 - (void)animate { int newX, newY; //New position int newW, newH; //New size [UIView animateWithDuration:someDuration delay:someDelay animations:^{ yourView.transform = CATransform3DMakeRotation(M_PI_2,1.0,0.0,0.0); //flip halfway yourView.frame = CGRectMake(newX/2, newY/2, newW/2, newH/2); } completion:^{ while ([yourView.subviews count] > 0) [[yourView.subviews lastObject] removeFromSuperview]; // remove all subviews // Add your new views here [UIView animateWithDuration:someDuration delay:someDelay animations:^{ yourView.transform = CATransform3DMakeRotation(M_PI,1.0,0.0,0.0); //finish the flip yourView.frame = CGRectMake(newX, newY, newW, newH); } completion:^{ // Flip completion code here }]; }]; } 

Hope this helps!

+1
source share

I highly recommend taking a look at this post.

You do not need to process all this animation yourself.

If you use the class method UIView transitionFromView: toView: duration: options: completion: and pass UIViewAnimationOptionTransitionFlipFromLeft or UIViewAnimationOptionTransitionFlipFromRight - no matter what method you use, you want the animation to turn upside down.

I used the same as shown in the MLB application using this method. Your from view will be a cell in the grid, and to view will be what would be on the "back side" of the cell.

Hope this reduces the overall code you need.

0
source share

I would use a UICollectionView with a custom UICollectionViewCell and animate it with delegate delegations ... Just an example for others.

 #pragma mark - UICollectionViewDelegate - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath: (NSIndexPath *)indexPath { [UIView beginAnimations:@"showImage" context:Nil]; CGRect cellFrame = cell.frame; CGRect imgFram = cell.imageView.frame; [UIView setAnimationDuration:0.8]; [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:cell cache:YES]; cellFrame.size = CGSizeMake(200, 200); cellFrame.origin.y = 10; cellFrame.origin.x = 45; cell.frame = cellFrame; imgFram.size = CGSizeMake(200, 200); cell.imageView.frame = imgFram; [collectionView bringSubviewToFront:cell]; [UIView commitAnimations]; } 
0
source share

All Articles