I have a view controller that I am trying to pop. The animation that I would like to use is the same as the animation that would show when dismissViewController would be called. What would be the best way to replicate this for popToRootViewController. I know how to create custom view controller animations, but I was wondering what will be the best way to do this?
To control the animation that happens when you call popToRootViewControler, you'll just need to set your navigation controller's delegate and implement the UINavigationControllerDelegate method:
- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC
From there, you'll return self or any object where you can implement the UIViewControllerAnimatedTransitioning method:
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
Related
I need to pass an object to the root view controller of an UINavigationController before it appears. I have its root view controller relationship set in storyboard, and it seems that I can't handle it like the other types of segues.
How could I do this?
Thanks
You could assign the UINavigationController a delegate and implement the method -
- (void)navigationController:(UINavigationController *)navigationController
willShowViewController:(UIViewController *)viewController
animated:(BOOL)animated {
// check viewController is kind of class, check any flags
// pass object to vc
}
the project I am working on needs to have a custom transition between two view controllers. I have setup and implemented UIViewControllerTransitioningDelegate by overriding the method like:
- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
animationControllerForOperation:(UINavigationControllerOperation)operation
fromViewController:(UIViewController *)fromVC
toViewController:(UIViewController *)toVC
{
//Creation of animation
id<UIViewControllerAnimatedTransitioning> animationController;
MyAnimator *animator = [[MyAnimator alloc] init];
animator.appearing = YES;
animationController = animator;
return animator
}
And I have setup MyAnimator subclass to correctly implement UIViewControllerAnimatedTransitioning by overriding the method:
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
//custom transition animation
}
The segue which I using to trigger this animation transition is created and called programmatically, like:
UIStoryboardSegue *segue = [[UIStoryboardSegue alloc] initWithIdentifier:#"showCardDetail" source:self destination:vc];
[self prepareForSegue:segue sender:self];
[segue perform];
Reason of creating segue programmatically: I have from(transition from) and to(transition to) view controllers in separate storyboards.
Problem / Question:
I have seen many examples, all handle the custom transition using a storyboard segue like:
[self performSegueWithIdentifier:#"storyboardSegue-id" sender:self]
How should i define in the method -perform for segue created programmatically above so that the custom transition takes place.
You don't need to create a custom segue to do what you're trying to do. In fact, since you have your 2 controllers in separate storyboards, you shouldn't use a segue at all. Just instantiate your destination view controller, and use pushViewController:animated: to initiate the transition. Your first view controller should be the delegate of the navigation controller, so the delegate method you show at the top of your question gets called.
In navigationControllerAnimationControllerForOperation:fromViewController:toViewController: you can adjust source and destination viewControllers and based on this types you will see desired animation. You do not need to use prepareForSegue: here.
I'm implementing my own UINavigationController transition using:
- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
animationControllerForOperation:(UINavigationControllerOperation)operation
fromViewController:(UIViewController *)fromVC
toViewController:(UIViewController *)toVC{
return self;
}
What happens though, the pushing viewController.view disappears as soon as the transition finishes. I present views using
[self.navigationController pushViewController:pushedViewController animated:YES];
Is there a way to tell TransitionCoordinator not to delete the presenting controller's view when I push them using UINavigationController? Do I really need to implement my own ContainerView with all the logic?
I finished up making my own ContainerViewController. Now I have total control over views' lifespan.
I have a View Controller that has a custom push transition when a table cell is tapped and performs the standard pop transition when the back bar button item is tapped. The problem is when I try to go to the same view controller from the previous controller, the app crashes. Below is the UINavigationControllerDelegatefunction I'm implementing:
- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC
{
return (operation == UINavigationControllerOperationPush ? animator : nil);
}
Any clue is appreciated!
Thanks in advance.
I had a problem, where the NavigationController's delegate was set to a view controller that had been deallocated, which caused a crash in [UINavigationController _customTransitionController:].
Especially when using unwind segues, it does NOT seem that any intermediate view controllers receive a viewWillDisappear callback before getting deallocated. The remedy here is to implement the following in the destination unwind view controller:
-(IBAction)unwindSegue:(UIStoryboardSegue*)segue{
self.navigationController.delegate = nil;
}
I want to save DB when the back button clicked in navigation controller.
so I would insert code in method.
What method is called when back button clicked in navigation controller?
To do what you asked, look at the UINavigationControllerDelegate protocol, namely the method:
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
when the viewController argument is no longer your view controller then you should save.
However, doing so on viewWillDisappear: might be a better (and much simpler) idea.
Maybe it's not appropriate use, but that worked for me. Don't forget to set UINavaigationController delegate.
- (id <UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
animationControllerForOperation:(UINavigationControllerOperation)operation
fromViewController:(UIViewController *)fromVC
toViewController:(UIViewController *)toVC
{
NSLog(#"from VC class %#", [fromVC class]);
if ([fromVC isKindOfClass:[ControllerYouJustPopped class]])
{
NSLog(#"Returning from popped controller");
}
return nil;
}