2

I have a custom button on a view controller in the navigation controller's heirarchy, that when pressed, pops the visible view controller.

I want to use UIView's transform property to animate the closing of the view controller. It works, but if I use `popViewControllerAnimated:YES', the default left slide of the animation is still there, though my custom transform also works.

If I set popViewControllerAnimated:NO it doesn't animate anything at all.

I also looked into using CATransition which works when I have popViewControllerAnimated set to NO, but there isn't a "zoom" effect that's part of the public API, and I don't want to use the private effect. Custom filters are also not available for iPhone, only OS X.

So I guess my questions are:

1) Is there a way to remove the the left slide in the default transition yet still have a custom animation using transform?

2) Some way to use a custom filter for CATransition?

3) If I use a private API for the zoom effect how likely will Apple toss my app in the rejection bin?

Does anyone have a solution I'm overlooking?

Calvin
  • 8,697
  • 7
  • 43
  • 51

1 Answers1

6

I've done something similar to what you describe, i.e. change the default animation for pop and push of view in UINavigationController.

The idea is to disable the default animation for the object and replace it with your own animation. I've created a new category for UINavigationController and used a function similar to the one below.

 - (void) altAnimatePopViewControllerAnimated:(BOOL)animated
 {
[CATransaction begin];

CATransition *transition;
transition = [CATransition animation];
transition.type = kCATransitionPush;          // Use any animation type and subtype you like
transition.subtype = kCATransitionFromTop;
transition.duration = 0.3;

CATransition *fadeTrans = [CATransition animation];
fadeTrans.type = kCATransitionFade;
fadeTrans.duration = 0.3;


[CATransaction setValue:(id)kCFBooleanTrue
                 forKey:kCATransactionDisableActions];

[[[[self.view subviews] objectAtIndex:0] layer] addAnimation:transition forKey:nil];
[[[[self.view subviews] objectAtIndex:1] layer] addAnimation:fadeTrans forKey:nil];



[self  popViewControllerAnimated:YES];
[CATransaction commit];
   }

to use just use the code

   [self.navigationController altAnimatePopViewControllerAnimated:YES];

In order to do a push just create another similar function and reverse the animation.

It's not perfect but it works. When you choose different animation types play around with the different subviews composing the navigation bar/controller to get it perfect.

Took my quite a white to come up with this, so use it wisely :)

******* EDIT

Try replacing the push transition with this (Didn't try it myself):

  CAKeyframeAnimation *scale = [CAKeyframeAnimation animationWithKeyPath:@"transform.scale"];
  scale.duration = duration;
  scale.values = [NSArray arrayWithObjects:[NSNumber numberWithFloat:.5f],
              [NSNumber numberWithFloat:1.2f],
              [NSNumber numberWithFloat:.85f],
              [NSNumber numberWithFloat:1.f],
              nil];

This will do a pop in, i.e. the view will be bigger before it settles to the right size. Play with the values in the array to control the curve of the animation.

Ron Srebro
  • 6,663
  • 3
  • 27
  • 40
  • Thanks for your tip. Unfortunately though I need to be able to use the `UIView` animation using the `transform` property so that I can scale the view from a small point to full-size, to get a zooming effect. There seems to be no way to do that using `CATransition`. :( – Calvin Aug 04 '10 at 06:41
  • I haven't tried it, but what if you just replace the CATransition in my code with CABasicAnimation? See updated answer for how to animate the frame of a view with CABasicAnimation – Ron Srebro Aug 04 '10 at 07:44
  • OK, I don't think it can be done with CABasicAnimation, but rather with CAkeyframeAnimation. see answer. – Ron Srebro Aug 04 '10 at 07:55
  • This is very cool -- thanks! I've got a nice basic scale "zoom out" effect working, but the background during the scaling is white. Any idea how I can remove that and make it transparent? – Calvin Aug 05 '10 at 00:48
  • Is there anything beneath the view? What do you want to see instead of the white? – Ron Srebro Aug 05 '10 at 01:06
  • I want to see the view that's under the view that's being "zoomed out". Once the animation finishes the view pops into view, but only after the white disappears. – Calvin Aug 05 '10 at 01:09
  • For the sake of future people finding this question, I've posted a similar question here: http://stackoverflow.com/questions/4044181/iphone-uinavigationcontroller-custom-animation-with-catransaction. – RyanJM Oct 28 '10 at 15:08
  • Excellent! This should be higher up in the search results. Spent ages trying to get this to work and this worked perfectly! Thanks – Fogmeister Jul 04 '12 at 07:46