Custom animation while transitioning between view controllers - ios

I want to create transition between view controllers like this.
https://www.dropbox.com/s/qatwqaq2mowocsg/Transitions%20Controller.gif?dl=0
I 've used the following code to create transition but cannot achieve following results.
self.settings = [self.storyboard instantiateViewControllerWithIdentifier:#"settings"];
CATransition* transition = [CATransition animation];
transition.duration = 0.4;
transition.type = kCATransitionPush;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionDefault];
transition.subtype=kCATransitionFromRight;
[[self navigationController].view.layer addAnimation:transition forKey:kCATransition];
[[self navigationController] pushViewController:self.settings animated:NO];

You can try this code :
self.settings = [self.storyboard instantiateViewControllerWithIdentifier:#"settings"];
[UIView beginAnimations:#"View Flip" context:nil];
[UIView setAnimationDuration:0.80];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition:
UIViewAnimationTransitionFlipFromRight
forView:self.navigationController.view cache:NO];
[self.navigationController pushViewController:self.settings animated:YES];
[UIView commitAnimations];

Start from iOS7 you can custom the transition effect of system method pushViewController and presentViewController. For example if you need to custom the push effect there is a method in UINavigationControllerDelegate named
- (id<UIViewControllerAnimatedTransitioning> _Nullable)navigationController:(UINavigationController * _Nonnull)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController * _Nonnull)fromVC toViewController:(UIViewController * _Nonnull)toVC
add the custom animation to fromVC's view and show the toVC's view in proper time

While it's not a direct implementable chunk of code that represents THE ANSWER, this blog should get you through the steps to create your own custom transitions: http://blog.dadabeatnik.com/2013/10/13/custom-segues/

Related

PresentViewController with custom animation

I need to present view controller with UIViewAnimationOptionCurveEaseIn animation where source controller disappear from 1 alpha to 0 and destination controller appear from 0 alpha to 1
I'd like to use
presentViewController: animated: completion:
I've tried:
In source controller
UIStoryboard *st = [UIStoryboard storyboardWithName:[[NSBundle mainBundle].infoDictionary objectForKey:#"UIMainStoryboardFile"] bundle:[NSBundle mainBundle]];
PopViewController *pop = [st instantiateViewControllerWithIdentifier:name];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:pop];
nav.navigationBarHidden = YES;
[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
self.view.alpha = 0.f;
} completion:^(BOOL finished) {
[self presentViewController:nav animated:NO completion:nil];
}];
In destination controller
- (void)viewDidLoad{
[super viewDidLoad];
self.view.alpha = 0.f;
[UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionCurveEaseIn animations:^{
self.view.alpha = 1.f;
} completion:^(BOOL finished) {
}];
but controllers disappear and appear not at the same time
Pavel, for example
-(void)goToViewControllerAction
{
[CATransaction begin];
[CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
CATransition *transition = [CATransition animation];
[transition setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]];
transition.duration = 1.5;
[transition setType:kCATransitionFade];
[self.navigationController.view.layer addAnimation:transition forKey:#"someAnimation"];
[self performSegueWithIdentifier:#"backPopsegue" sender:nil];// Here your push or performSegue transition
[CATransaction commit];
}
Don't remember to use QuartzCore)
You can customize your transition like you want, there are a lot of different settings in it....

Sliding a view controller from bottom with a Gesture

I have a question (Objective-C related).
I want to create a sliding from bottom ViewController on top of the Root Map View Controller by a click on the annotation.
1) After a click on the annotation it should slide from bottom and show 10% of the height;
2) after an upward swipe gesture - it should show up to 100% if the user drags it upwards fully;
3) on the downward gesture user should be able to decrease its visible height to 10% again;
4) on the MapView click the bottom ViewController should hide.
I'm including the Visual scheme of the process implementation.
Any ideas are very very appreciated!
check this demo
NHSlidingController
PanningViewController
You can always try to write your own segue animation to transition between ViewControllers. Just make a custom UIStoryboardSegue, and override its perform method. Here is a snippet to start with:
#interface HorizontalSegue : UIStoryboardSegue
#property CGPoint originatingPoint;
#end
#implementation VerticalSegue
- (void)perform {
UIViewController *sourceViewController = self.sourceViewController;
UIViewController *destinationViewController = self.destinationViewController;
NSArray* windowArray = [UIApplication sharedApplication].windows;
if (windowArray.count > 0) {
UIWindow* appWindow = [windowArray lastObject];
[appWindow insertSubview:destinationViewController.view aboveSubview:sourceViewController.view];
}
else
[sourceViewController.view addSubview:destinationViewController.view];
// Store original centre point of the destination view
CGPoint originalCenter = destinationViewController.view.center;
// Set center to start point of the button
destinationViewController.view.center = CGPointMake(self.originatingPoint.x, self.originatingPoint.y*3);
[UIView animateWithDuration:0.25
delay:0.0
options:UIViewAnimationOptionCurveEaseInOut
animations:^{
destinationViewController.view.center = originalCenter;
}
completion:^(BOOL finished){
[sourceViewController presentViewController:destinationViewController animated:NO completion:NULL]; // present VC
}];
}
#end
Using this you can easily make custom animations. I am not totally sure if the part with adding the ViewController to the window is correct, but this is something that you could try and check/correct yourself.
Another way of animating segues is using CATransition:
-(void)perform
{
UIViewController *sourceViewController = (UIViewController*)[self sourceViewController];
UIViewController *destinationController = (UIViewController*)[self destinationViewController];
CATransition* transition = [CATransition animation];
transition.duration = 0.25;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionMoveIn; //kCATransitionMoveIn; //, kCATransitionPush, kCATransitionReveal, kCATransitionFade
transition.subtype = kCATransitionFromLeft; //kCATransitionFromLeft, kCATransitionFromRight, kCATransitionFromTop, kCATransitionFromBottom
[destinationController.view.layer addAnimation:transition forKey:kCATransition];
[sourceViewController presentViewController:destinationController animated:NO completion:nil];
}

Push and Pop animations in a navigation based app

I have a navigation based application and I want to change the animation of the push and pop animations. How would I do that?
When i push any viewController it represent as pop and When i pop any viewController it represent as push.
CATransition *transition = [CATransition animation];
transition.duration = 0.3f;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionPush;
transition.subtype=kCATransitionFromRight;
kCATransitionFromLeft or kCATransitionFromRight
[self.navigationController.view.layer addAnimation:transition forKey:nil];
add this before you push the view controller for custom animation
-(void)pushViewController:(UIViewController *)viewController{
float width = self.frame.size.width;
float height = self.frame.size.height;
[viewController.view setFrame:CGRectMake(width, 0.0, width, height)];
[self addSubview:viewController.view];
[UIView animateWithDuration:0.33f
delay:0.0f
options:UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionAllowUserInteraction
animations:^{
[viewController.view setFrame:self.frame];
[self setFrame:CGRectMake(0.0, 0.0, width, height)];
}
completion:^(BOOL finished){
}];
}

Stop UITableView Animation on push to UINavigationController

I'm pushing a view controller that contains a tableiview onto my uinavigation controller:
CourseMenuViewController *mvc = [[[CourseMenuViewController alloc] initWithSlidingNavigationcontroller:self.slidingNavigationController] autorelease];
mvc.course = course;
[self.navigationController pushViewController:mvc animated:YES];
[self.navigationController setNavigationBarHidden:NO animated:NO];
So far so good, everything works as expected. My issue occurs when I watch the animation and see all of my table view rows animate down from the top of the screen as the view is animating in from the left. This makes it feel like the view is moving from the top-left corner to the bottom-right corner in a diagonal path.
My question is, how can I make the table view just appear instead of animating? I should add that all of my cells are static so I'm not waiting on any data from a NSFetchedResultsController or anything like that.
roronoa below put me on the right path, and here is the now working version:
CourseMenuViewController *mvc = [[[CourseMenuViewController alloc] initWithSlidingNavigationcontroller:self.slidingNavigationController] autorelease];
mvc.course = course;
CATransition *caTransition = [CATransition animation];
caTransition.duration = 0.35;
caTransition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
caTransition.delegate = self;
caTransition.type = kCATransitionPush;
caTransition.subtype = kCATransitionFromRight;
[self.navigationController.view.layer addAnimation:caTransition forKey:nil];
[self.navigationController pushViewController:mvc animated:NO];
You have not mentioned details about your class CourseMenuViewController and initWithSlidingNavigationcontroller , but you can use the following to get the job done:-
CourseMenuViewController *mvc =[[CourseMenuViewController alloc] init];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:1.0];
[self.navigationController pushViewController:mvc animated:NO];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.navigationController.view cache:NO];
[UIView commitAnimations];
[mvc release];
you can have any type of animation that you want in the above code by changing the animation constants according to your need without having unwanted animations on your tableview.

Showing pushviewcontroller animation look like presentModalViewController

Is it possible to show pushViewController animation look like presentModalViewController but that has background functionality of pushViewController?
If you want to a fade animation, this approach works.
CATransition* transition = [CATransition animation];
transition.duration = 0.3;
transition.type = kCATransitionFade;
transition.subtype = kCATransitionFromTop;
[self.navigationController.view.layer addAnimation:transition forKey:kCATransition];
[self.navigationController pushViewController:gridController animated:NO];
Try this :
UIViewController *yourViewController = [[UIViewController alloc]init];
[UIView beginAnimations: #"Showinfo"context: nil];
[UIView setAnimationCurve: UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:0.75];
[self.navigationController pushViewController: yourViewController animated:NO];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.navigationController.view cache:NO];
[UIView commitAnimations];
For display PushViewConttroler animation as Present below code is working,
For Push
ViewController *VC = [self.storyboard instantiateViewControllerWithIdentifier:#"ViewController"];
CATransition* transition = [CATransition animation];
transition.duration = 0.4f;
transition.type = kCATransitionMoveIn;
transition.subtype = kCATransitionFromTop;
[self.navigationController.view.layer addAnimation:transition
forKey:kCATransition];
[self.navigationController pushViewController:VC animated:NO];
And for POP
CATransition* transition = [CATransition animation];
transition.duration = 0.4f;
transition.type = kCATransitionReveal;
transition.subtype = kCATransitionFromBottom;
[self.navigationController.view.layer addAnimation:transition
forKey:kCATransition];
[self.navigationController popViewControllerAnimated:NO];
There is 1 issue though, that its display light black background when its going up/down,
Working on that, As soon as its done post new code here.
For All Trying in Xamarin (C#) equivalent Code
From Answer by #hardik Thakkar above, Has the issue of Black backgound during animation, rest all good.
For POP
CATransition transition = CATransition.CreateAnimation();
transition.Duration = 0.4;
transition.Type = CAAnimation.TransitionReveal;
transition.Subtype = CAAnimation.TransitionFromTop;
this.NavigationController.View.Layer.AddAnimation(transition, nameof(CATransition));
For Push
CATransition transition = CATransition.CreateAnimation();
transition.Duration = 0.4;
transition.Type = CAAnimation.TransitionReveal;
transition.Subtype = CAAnimation.TransitionFromBottom;
this.NavigationController.View.Layer.AddAnimation(transition, nameof(CATransition));
You should consider doing something like:
ViewController *myVC = [[ViewController alloc] initWithFrame:OFF_SCREEN];
[navigationController pushViewController:myVC animated:NO];
where OFF_SCREEN is some CGRect below the screen, like (0, 481, 320, 480). Then use an animation block to adjust the viewcontroller's view's frame.origin to be (0, 0). You would probably want to do the animate block in viewDidLoad or viewDidAppear.

Resources