Search code examples
iosuiviewuiviewanimationcatransform3d

Having Fun With UIView Animations And UIView Flipping


(My apologies for the long post) To jazz up my AQGridView, the attached code copies the selected cell into a UIView, then animates that view to expand to fill the screen, then have said view transform to look like a full screen cover animation. Feel free to reuse, but that's not my problem. My problem is the animation for Landscape, which must be different. I wish to animate my cell view to the right half of the screen and expand to fill the right half of the screen (already accomplished) then have it do a y flip rotation across the screen to the left side. Anchor points at CGPointMake(0.5, 0.5); don't work, and neither does setting the translate x value to half of the screen and back again, it just performs, then flies off the screen! HELP!!

EDIT: (The code is now working thanks to me not realizing that I had been adding the new UIView's to the self.navigationController.view property, so all it took was to render that and flip it, no translations needed!) WORKING CODE:

if(UIInterfaceOrientationIsPortrait(viewController.interfaceOrientation)) {
            self.view.userInteractionEnabled = NO;

            [self.navigationController.view addSubview:viewForCopy];
            [self.navigationController.view bringSubviewToFront:viewForCopy];
            [viewForCopy setFrame:CGRectMake([_gridView rectForItemAtIndex:index].origin.x, [_gridView rectForItemAtIndex:index].origin.y + 65, [_gridView rectForItemAtIndex:index].size.width, [_gridView rectForItemAtIndex:index].size.height)];
            [viewForCopy setAlpha:1.0f];

            [[_gridView cellForItemAtIndex:index] setAlpha:0.0f];

            [UIView animateWithDuration:1.5f
                                  delay:0.0f
                                options:UIViewAnimationCurveEaseInOut
                             animations:^{
                                 [self.navigationController.navigationBar setAlpha:0.0f];
                                 [newShadow removeFromSuperlayer];
                                 [viewForCopy setFrame:CGRectMake(-158, 10, self.view.bounds.size.width * 1.55, self.view.bounds.size.height * 1.25)];
                                 [self.navigationController.navigationBar setAlpha:0.0f];  
                             } 
                             completion:^(BOOL finished) {
                                 [UIView animateWithDuration:2.0f
                                                       delay:0.0f
                                                     options:UIViewAnimationCurveEaseInOut
                                                  animations:^{
                                                      [viewForCopy setAlpha:0.0f];
                                                      CATransform3D _3Dt = CATransform3DIdentity;
                                                      _3Dt = CATransform3DTranslate(_3Dt, viewForCopy.frame.size.width * -1, 0, 0);
                                                      _3Dt = CATransform3DRotate(_3Dt, M_PI / -2.0f, 0.0f, 0.1f, 0.0f);  
                                                      _3Dt.m34 = 1.0f / 500.0f;
                                                      _3Dt = CATransform3DTranslate(_3Dt, viewForCopy.frame.size.width, 0, 0);
                                                      viewForCopy.layer.transform = _3Dt;
                                                      [UIView setAnimationTransition:UIViewAnimationTransitionNone forView:self.navigationController.view cache:YES];
                                                      [self.navigationController pushViewController:viewController animated:NO];

                                                  } 
                                                  completion:^(BOOL finished) {
                                                  }];
                                 [[_gridView cellForItemAtIndex:index] setAlpha:1.0f];
                                 [self.navigationController.view sendSubviewToBack:viewForCopy];

                             }];
        }
             else if(UIInterfaceOrientationIsLandscape(viewController.interfaceOrientation)){
                 UIView *viewforCopyLandscape2 = [[[UIView alloc]initWithFrame:CGRectMake([_gridView rectForItemAtIndex:index].origin.x, [_gridView rectForItemAtIndex:index].origin.y + 65, [_gridView rectForItemAtIndex:index].size.width, [_gridView rectForItemAtIndex:index].size.height)]autorelease];
                 viewforCopyLandscape2.backgroundColor = [UIColor whiteColor];
                 viewforCopyLandscape2.alpha = 0.0f;

                 [self.navigationController.view addSubview:viewforCopyLandscape2];
                 [self.navigationController.view bringSubviewToFront:viewforCopyLandscape2];
                 [self.navigationController.view addSubview:viewForCopy];
                 [self.navigationController.view bringSubviewToFront:viewForCopy];

                 [newShadow removeFromSuperlayer];

                 [viewForCopy setFrame:CGRectMake([_gridView rectForItemAtIndex:index].origin.x, [_gridView rectForItemAtIndex:index].origin.y + 65, [_gridView rectForItemAtIndex:index].size.width, [_gridView rectForItemAtIndex:index].size.height)];

                 [[_gridView cellForItemAtIndex:index] setAlpha:0.0f];

                 self.view.userInteractionEnabled = NO;

                 [UIView animateWithDuration:1.5f
                                       delay:0.0f
                                     options:UIViewAnimationCurveEaseInOut
                                  animations:^{
                                      [viewforCopyLandscape2 setFrame:CGRectMake(0, 20, self.view.bounds.size.width/2, self.view.bounds.size.height)];
                                      [viewForCopy setFrame:CGRectMake(407, 10, self.view.bounds.size.width * .78, self.view.bounds.size.height * 1.25)];
                                      [self.navigationController.navigationBar setAlpha:0.0f];  
                                      viewforCopyLandscape2.alpha = 1.0f;
                                  } 
                                  completion:^(BOOL finished) {

                                      UIView *viewForCopyLandscape = [[[UIView alloc]initWithFrame:CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y, self.view.bounds.size.width, self.view.bounds.size.height)]autorelease];
                                      UIGraphicsBeginImageContext(CGSizeMake(self.view.bounds.size.width, self.view.bounds.size.height));
                                      [self.navigationController.view.layer renderInContext:UIGraphicsGetCurrentContext()];
                                      UIImageView *viewImage = [[[UIImageView alloc]initWithImage:UIGraphicsGetImageFromCurrentImageContext()]autorelease];
                                      UIGraphicsEndImageContext();
                                      viewForCopyLandscape = viewImage;
                                      [self.navigationController.view addSubview:viewForCopyLandscape];
                                      [self.navigationController.view bringSubviewToFront:viewForCopyLandscape];

                                      [viewForCopy setAlpha:0.0f];
                                      [UIView animateWithDuration:2.0f
                                                            delay:0.0f
                                                          options:UIViewAnimationCurveEaseInOut
                                                       animations:^{

                                                           CATransform3D transform = CATransform3DMakeRotation(-M_PI / 1.1, 0.0, 1.0, 0.0);
                                                           transform.m34 = 1.0f / 2500.0f;
                                                           viewForCopyLandscape.layer.transform = transform;

                                                           [self.navigationController.view sendSubviewToBack:viewForCopy];
                                                           [UIView setAnimationTransition:UIViewAnimationTransitionNone forView:self.navigationController.view cache:YES];
                                                           [self.navigationController pushViewController:viewController animated:NO];
                                                           [viewforCopyLandscape2 removeFromSuperview];

                                                       }           
                                                       completion:^(BOOL finished) {
                                                           [[_gridView cellForItemAtIndex:index] setAlpha:1.0f];
                                                           [viewForCopy removeFromSuperview];
                                                           [UIView animateWithDuration:1.00 animations:^ {
                                                               [viewForCopyLandscape setAlpha:0.0f];

                                                           }];
                                                       }];
                                  }];
}

Solution

  • The code is now working thanks to me not realizing that I had been adding the new UIView's to the self.navigationController.view property, so all it took was to render that and flip it, no translations needed!)

    if(UIInterfaceOrientationIsPortrait(viewController.interfaceOrientation)) {
                self.view.userInteractionEnabled = NO;
    
                [self.navigationController.view addSubview:viewForCopy];
                [self.navigationController.view bringSubviewToFront:viewForCopy];
                [viewForCopy setFrame:CGRectMake([_gridView rectForItemAtIndex:index].origin.x, [_gridView rectForItemAtIndex:index].origin.y + 65, [_gridView rectForItemAtIndex:index].size.width, [_gridView rectForItemAtIndex:index].size.height)];
                [viewForCopy setAlpha:1.0f];
    
                [[_gridView cellForItemAtIndex:index] setAlpha:0.0f];
    
                [UIView animateWithDuration:1.5f
                                      delay:0.0f
                                    options:UIViewAnimationCurveEaseInOut
                                 animations:^{
                                     [self.navigationController.navigationBar setAlpha:0.0f];
                                     [newShadow removeFromSuperlayer];
                                     [viewForCopy setFrame:CGRectMake(-158, 10, self.view.bounds.size.width * 1.55, self.view.bounds.size.height * 1.25)];
                                     [self.navigationController.navigationBar setAlpha:0.0f];  
                                 } 
                                 completion:^(BOOL finished) {
                                     [UIView animateWithDuration:2.0f
                                                           delay:0.0f
                                                         options:UIViewAnimationCurveEaseInOut
                                                      animations:^{
                                                          [viewForCopy setAlpha:0.0f];
                                                          CATransform3D _3Dt = CATransform3DIdentity;
                                                          _3Dt = CATransform3DTranslate(_3Dt, viewForCopy.frame.size.width * -1, 0, 0);
                                                          _3Dt = CATransform3DRotate(_3Dt, M_PI / -2.0f, 0.0f, 0.1f, 0.0f);  
                                                          _3Dt.m34 = 1.0f / 500.0f;
                                                          _3Dt = CATransform3DTranslate(_3Dt, viewForCopy.frame.size.width, 0, 0);
                                                          viewForCopy.layer.transform = _3Dt;
                                                          [UIView setAnimationTransition:UIViewAnimationTransitionNone forView:self.navigationController.view cache:YES];
                                                          [self.navigationController pushViewController:viewController animated:NO];
    
                                                      } 
                                                      completion:^(BOOL finished) {
                                                      }];
                                     [[_gridView cellForItemAtIndex:index] setAlpha:1.0f];
                                     [self.navigationController.view sendSubviewToBack:viewForCopy];
    
                                 }];
            }
                 else if(UIInterfaceOrientationIsLandscape(viewController.interfaceOrientation)){
                     UIView *viewforCopyLandscape2 = [[[UIView alloc]initWithFrame:CGRectMake([_gridView rectForItemAtIndex:index].origin.x, [_gridView rectForItemAtIndex:index].origin.y + 65, [_gridView rectForItemAtIndex:index].size.width, [_gridView rectForItemAtIndex:index].size.height)]autorelease];
                     viewforCopyLandscape2.backgroundColor = [UIColor whiteColor];
                     viewforCopyLandscape2.alpha = 0.0f;
    
                     [self.navigationController.view addSubview:viewforCopyLandscape2];
                     [self.navigationController.view bringSubviewToFront:viewforCopyLandscape2];
                     [self.navigationController.view addSubview:viewForCopy];
                     [self.navigationController.view bringSubviewToFront:viewForCopy];
    
                     [newShadow removeFromSuperlayer];
    
                     [viewForCopy setFrame:CGRectMake([_gridView rectForItemAtIndex:index].origin.x, [_gridView rectForItemAtIndex:index].origin.y + 65, [_gridView rectForItemAtIndex:index].size.width, [_gridView rectForItemAtIndex:index].size.height)];
    
                     [[_gridView cellForItemAtIndex:index] setAlpha:0.0f];
    
                     self.view.userInteractionEnabled = NO;
    
                     [UIView animateWithDuration:1.5f
                                           delay:0.0f
                                         options:UIViewAnimationCurveEaseInOut
                                      animations:^{
                                          [viewforCopyLandscape2 setFrame:CGRectMake(0, 20, self.view.bounds.size.width/2, self.view.bounds.size.height)];
                                          [viewForCopy setFrame:CGRectMake(407, 10, self.view.bounds.size.width * .78, self.view.bounds.size.height * 1.25)];
                                          [self.navigationController.navigationBar setAlpha:0.0f];  
                                          viewforCopyLandscape2.alpha = 1.0f;
                                      } 
                                      completion:^(BOOL finished) {
    
                                          UIView *viewForCopyLandscape = [[[UIView alloc]initWithFrame:CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y, self.view.bounds.size.width, self.view.bounds.size.height)]autorelease];
                                          UIGraphicsBeginImageContext(CGSizeMake(self.view.bounds.size.width, self.view.bounds.size.height));
                                          [self.navigationController.view.layer renderInContext:UIGraphicsGetCurrentContext()];
                                          UIImageView *viewImage = [[[UIImageView alloc]initWithImage:UIGraphicsGetImageFromCurrentImageContext()]autorelease];
                                          UIGraphicsEndImageContext();
                                          viewForCopyLandscape = viewImage;
                                          [self.navigationController.view addSubview:viewForCopyLandscape];
                                          [self.navigationController.view bringSubviewToFront:viewForCopyLandscape];
    
                                          [viewForCopy setAlpha:0.0f];
                                          [UIView animateWithDuration:2.0f
                                                                delay:0.0f
                                                              options:UIViewAnimationCurveEaseInOut
                                                           animations:^{
    
                                                               CATransform3D transform = CATransform3DMakeRotation(-M_PI / 1.1, 0.0, 1.0, 0.0);
                                                               transform.m34 = 1.0f / 2500.0f;
                                                               viewForCopyLandscape.layer.transform = transform;
    
                                                               [self.navigationController.view sendSubviewToBack:viewForCopy];
                                                               [UIView setAnimationTransition:UIViewAnimationTransitionNone forView:self.navigationController.view cache:YES];
                                                               [self.navigationController pushViewController:viewController animated:NO];
                                                               [viewforCopyLandscape2 removeFromSuperview];
    
                                                           }           
                                                           completion:^(BOOL finished) {
                                                               [[_gridView cellForItemAtIndex:index] setAlpha:1.0f];
                                                               [viewForCopy removeFromSuperview];
                                                               [UIView animateWithDuration:1.00 animations:^ {
                                                                   [viewForCopyLandscape setAlpha:0.0f];
    
                                                               }];
                                                           }];
                                      }];
    }