I am coming from this question: How to change the Push and Pop animations in a navigation based app
I wanted to reverse the animation for push and pop. So that, instead of the default animating to Right, it should go to the Left and vice versa.
I created a subclass of UINavigationController and override the push and pop methods.
Here is the code:
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{
CATransition* transition = [CATransition animation];
transition.duration = 0.4;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionPush;//kCATransitionFade; //kCATransitionMoveIn; //, kCATransitionPush, kCATransitionReveal, kCATransitionFade
transition.subtype = kCATransitionFromLeft; //kCATransitionFromLeft, kCATransitionFromRight, kCATransitionFromTop, kCATransitionFromBottom
[self.view.layer addAnimation:transition forKey:nil];
[super pushViewController:viewController animated:NO];
}
- (UIViewController *)popViewControllerAnimated:(BOOL)animated
{
CATransition* transition = [CATransition animation];
transition.duration = 0.4;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionPush;//kCATransitionFade; //kCATransitionMoveIn; //, kCATransitionPush, kCATransitionReveal, kCATransitionFade
transition.subtype = kCATransitionFromRight; //kCATransitionFromLeft, kCATransitionFromRight, kCATransitionFromTop, kCATransitionFromBottom
[self.view.layer addAnimation:transition forKey:nil];
UIViewController *poppedVC = [super popViewControllerAnimated:NO];
return poppedVC;
}
So far, these are working perfectly.
In these methods, the line [self.view.layer addAnimation:transition forKey:nil]; is making me confused. I see that on every call to the methods a new CATransition object is initialized and added to the layer of the view. I am not sure whats the effect of this on memory. Is it safe and if not, what should I do so that it won't harm memory/performance?
An easy solution would be to add a CATransition ivar (or property) and reuse that every time. That said, I doubt this will affect performance noticeably and it's not usually useful to worry about performance until you've established that it is an issue.
So, in short, don't worry about it. If you ARE worried about it, make a single ivar that is used in each of these methods.
Related
I have to present a UIImagePickerController but when I do so, it always come from the bottom up. Is there a way to make it appear from the right to left?
I have tried this without success:
CATransition* transition = [CATransition animation];
transition.duration = 0.35f;
transition.type = kCATransitionPush;
transition.subtype = kCATransitionFromLeft;
[self.navigationController.view.layer addAnimation:transition forKey:kCATransition];
[self.navigationController presentModalViewController:picker animated:YES];
thanks
I assume you are currently displaying the picker by calling presentModalViewController:animated: and passing YES as the animated option.
What you can do instead is present without animating, and instead cover the appearance using your own transition animation. The example below would present from the right:
CATransition *transition = [CATransition animation];
transition.duration = 0.5;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionMoveIn;
transition.subtype = kCATransitionFromRight;
[self.view.window.layer addAnimation:transition forKey:nil];
[self presentModalViewController:pickerController animated:NO];
To use this you'll need to #import <QuartzCore/QuartzCore.h> and add the QuartzCore framework to the project.
I have implemented a non-default animation for when a new view is pushed onto the screen (see code below). For some reason once I implemented this code it caused my UIActivityIndicatorViews to stop working. They will been shown on the screen but not animate even when their isAnimating is true. I figure it is because of me changing the CATransition, but can't figure out how to fix it for the UIActivityIndicatorView.
change default animation for push
CATransition* fade = [CATransition animation];
fade.duration = 1.0;
fade.type = kCATransitionFade;
fade.subtype = kCATransitionFromTop;
[self.navigationController.view.layer
addAnimation:fade forKey:kCATransition];
later on in viewDidLoad I start the animation
[spinner startAnimating];
but the spinner will show and not animate. For some reason the very first spinner I have animates but after that nothing.
I was encountering this problem when using a CATransition inside a subclass of UINavigationController to have a custom animation when pushing or popping view controllers.
Inside a method of this UINavigationController's subclass I had this code:
- (void)addCustomTransition
{
CATransition* transition = [CATransition animation];
transition.duration = kAnimationDuration;
transition.timingFunction =
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionFade;
[self.view.layer addAnimation:transition forKey:nil];
}
However, I later found out you also have to add the same animation to the pushed/popped viewController's view's layer:
- (void)addCustomTransitionToViewController:(UIViewController *)viewController
{
CATransition* transition = [CATransition animation];
transition.duration = kAnimationDuration;
transition.timingFunction =
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionFade;
[self.view.layer addAnimation:transition forKey:nil];
[viewController.view.layer addAnimation:transition forKey:nil]; // this is what was missing
}
This pushed/popped view controller's view is that one that had an UIActivityIndicatorView that wasn't animating properly.
Hope this helps!
just change your time duration from 1.0 to 0.3 or less
just i am tested and it's working
I'm wondering if there is any chance to create a custom transition animation between Views, as a "cube":
http://www.pendrivelinux.com/wp-content/uploads/pdl-cubed.jpg
I've took a look for some example, without any success, do you know some, is even possible?
Thanks
UIViewController* viewCtrl = [[UIViewController alloc] init];
CATransition *transition = [CATransition animation];
transition.duration = 1;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = #"cube"; //Note: undocumented API, will probably cause App Store rejection
transition.subtype = kCATransitionFromLeft;
transition.delegate = self;
[self.navigationController.view.layer addAnimation:transition forKey:nil];
self.navigationController.navigationBarHidden = NO;
[self.navigationController pushViewController:viewCtrl animated:YES];
[viewCtrl release];
It should be possible. You will need to have 2 views and a bit of Core Animation 3D transforms.
I am looking to implement CATransitions within TTNavigator, I know the method
openURL can take a UIViewAnimationTransition but that only gives me
flipping and curling animations, but with CATransition I have access
to another 8, of which kCATransitionFromRight, kCATransitionFromLeft,
kCATransitionFromTop, kCATransitionFromBottom are the ones I am
specifically after.
With a UINavigationController would use something like this piece of code to
give me more control over the animation:
CATransition *transition = [CATransition animation];
transition.duration = 0.5f;
transition.timingFunction = [CAMediaTimingFunction
functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionPush;
[self.navigationController.view.layer addAnimation:transition
forKey:nil];
This code however, doesn't work with TTNavigator. Does anybody know
how I can get my own custom animations to work with TTNavigator? Or if
I am doing something wrong in my code?
Turns out i answered my own question, but rather than using that last line of code to set the animation on the navigationController i was trying to set the transition to the URLAction. Once i put that line back in and commented out the URLAction transition code it seems to work!
// create the URLAction
TTURLAction* urlAction;
urlAction = [TTURLAction actionWithURLPath:#"tt://Images"];
[urlAction applyAnimated:YES];
// create the CATransition and set it to the navigation controller
CATransition *transition = [CATransition animation];
transition.duration = 0.5f;
transition.timingFunction = [CAMediaTimingFunction
functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionPush;
[self.navigationController.view.layer addAnimation:transition
forKey:nil];
// tell the navigator to run the action
[[TTNavigator navigator] openURLAction:urlAction];
Hope this helps someone else in the future!
You can easily add flip or any other kind of animation on TTNavigator using TTLauncherView as follows:
- (void)launcherView:(TTLauncherView*)launcher didSelectItem:(TTLauncherItem*)item {
TTURLAction* action = [TTURLAction actionWithURLPath:item.URL];
[action setAnimated:YES];
[action setTransition:UIViewAnimationTransitionFlipFromLeft];
[[TTNavigator navigator] openURLAction:action];
}
This makes TTNavigator use animated transition while displaying new URL.
I have a UIView that I use as a container for four separate subviews. At any one time, only one of the subviews is visible and the rest are hidden. Right now, when switching between the views, all I am working with is setting or inserting the hidden property.
I'd like to have some sort of an animated transition to give the app a bit more polish, but can't quite make sense of some of the other posts I've read.
Could someone walk me through how to animate transitions from one subviews to another within a containing UIView?
Thanks!
Try to read about transitionFromView:toView:duration:options:completion: here
Try playing around with this code. This must be very close to what you need.
CATransition *transition = [CATransition animation];
transition.duration = 0.5;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionPush;
transition.subtype = kCATransitionFromLeft;
transition.delegate = self;
[self.navigationController.view.layer addAnimation:transition forKey:nil];
self.navigationController.navigationBarHidden = NO;
[self.navigationController popViewControllerAnimated:YES]
;