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....
Related
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/
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];
}
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){
}];
}
I'm currently using the following code in order to present my view controller.
CATransition* transition = [CATransition animation];
transition.duration = 1;
transition.type = kCATransitionFade;
transition.subtype = kCATransitionFromBottom;
[self.view.window.layer addAnimation:transition forKey:kCATransition];
[self presentViewController:viewController animated:NO completion:nil];
I need to use more complex animation utilizing UIView animateWithDuration method. It is just modal presentation and background view controller should stay there. How can I animate presenting view controller's view?
Update: next version of code :)
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"Main" bundle:NULL];
RootViewControllerEx *viewController = (RootViewControllerEx *)[sb instantiateViewControllerWithIdentifier:#"SB_RDVC"];
viewController.transitioningDelegate = self;
viewController.modalPresentationStyle = UIModalPresentationCustom;
[self presentViewController:viewController animated:YES completion:nil];
...
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
...
}
VC in storyboard doesn't have any segue specified, it stays lonely in storyboard :)
You need to use UIModalPresentationCustom as your UIViewController's modalPresentationStyle.
You then need to create a class that conforms to the UIViewControllerTransitioningDelegate and set that your on presentedViewController.
Example
YourViewController *viewController = [[YourViewController alloc] init];
viewController.delegate = self;
viewController.transitioningDelegate = self;
viewController.modalPresentationStyle = UIModalPresentationCustom;
[self.navigationController presentViewController:viewController animated:YES completion:nil];
You must then implement the following method:
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source;
Which returns an object that conforms to a UIViewControllerAnimatedTransitioning protocol, that implements the following method:
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
UIView *inView = [transitionContext containerView];
UIView *toView = [[transitionContext viewControllerForKey:UITransitionContextToViewControllerKey] view];
toView.frame = //CGRectMake(0,0,0,0);
[inView addSubview:toView];
// Use whatever animateWithDuration you need
[UIView animateWithDuration:0.6f delay:0.0f usingSpringWithDamping:0.7f initialSpringVelocity:0.5f options:UIViewAnimationOptionCurveEaseIn animations:^{
// Custom animation here
} completion:^(BOOL finished) {
// IMPORTANT
[transitionContext completeTransition:YES];
}];
}
Always remember to tell the context when a transition is complete, otherwise you'll enter an unstable state.
I have a litle problem. I have a pushviewcontroller and it uses an animation.
My code is like this:
[UIView beginAnimations: #"Showinfo"context: nil];
[UIView setAnimationCurve: UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:0.75];
[self.navigationController pushViewController:dtv animated:YES];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.navigationController.view cache:NO];
[UIView commitAnimations];`
It works good, but when the view is pushed and I go back, this doesn't do the animation.
So I don't know how to do the same animation when I go back.
can anyone help me? Thanks!
As an alternate, you can use this also,
CATransition* transition = [CATransition animation];
transition.duration = 0.5;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionFade; //kCATransitionMoveIn; //, kCATransitionPush, kCATransitionReveal, kCATransitionFade
//transition.subtype = kCATransitionFromTop; //kCATransitionFromLeft, kCATransitionFromRight, kCATransitionFromTop, kCATransitionFromBottom
[self.navigationController.view.layer addAnimation:transition forKey:nil];
[[self navigationController] popViewControllerAnimated:NO];
This is how I've always managed to complete this task.
For Push:
[UIView beginAnimations: #"Showinfo"context: nil];
[UIView setAnimationCurve: UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:0.75];
[self.navigationController pushViewController:dtv animated:YES];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.navigationController.view cache:NO];
[UIView commitAnimations];`
For Pop:
[
UIView beginAnimations: #"Showinfo"context: nil];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:0.75];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.navigationController.view cache:NO];
[UIView commitAnimations];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDelay:0.375];
[self.navigationController popViewControllerAnimated:NO];
[UIView commitAnimations];
I still get a lot of feedback from this so I'm going to go ahead and update it to use animation blocks which is the Apple recommended way to do animations anyway.
For Push:
MainView *nextView = [[MainView alloc] init];
[UIView animateWithDuration:0.75
animations:^{
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[super pushViewController:nextView animated:NO];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.navigationController.view cache:NO];
}];
For Pop:
[UIView animateWithDuration:0.75
animations:^{
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition:transition forView:self.navigationController.view cache:NO];
}];
[self.navigationController popViewControllerAnimated:NO];