I am trying to make an app and the first step is to create viewControllers and link them . I know i can do that using storyboards and sueges but i wanted to do it the old school way - by coding i.e.
It contains 4 view controllers
-MainViewController
-SettingsViewController
-RulesViewController
The three view controllers are managed using ContainerViewController
(4th viewController) (custom container which i wrote) . The currentSubViewController
keeps track of the viewController currently being shown
@implementation ContainerViewController
{
UIViewController * currentSubViewController;
}
All three viewControllers are created from .nib
On start up :
currentSubViewController is set to an instance of MainViewController and then
[container addChildViewController: currentSubViewController]
makes container the parent of currentSubViewController.
And the main page shows up without any problems
After start up on pressing the "settings button"
IBAction in MainViweController is called
- (IBAction)onSettings:(id)sender {
if ([self parentViewController]) {
[(ContainerViewController*)[self parentViewController showViewControllerWithName:@"settings"];
}
}
And then showViewControllerWithName
of ContainerViewController
is called
- (void) showViewControllerWithName:(NSString*)vctype
{
UIViewController * toVC = [ViewControllerFactory getViewControllerOfType:vctype]; // viewController factory returns the appropriate viewController i.e either MainViewController or SettingsViewController or RulesViewController
toVC.view.frame = containerView.bounds;
toVC.view.autoresizingMask = containerView.autoresizingMask;
[currentSubViewController willMoveToParentViewController:nil];
[self addChildViewController:toVC];
[self transitionFromViewController:currentSubViewController
toViewController:toVC duration:1.0 options:UIViewAnimationOptionCurveLinear animations:^{} completion:^(BOOL finished){
[currentSubViewController removeFromParentViewController];
[toVC didMoveToParentViewController:self];
}];
currentSubViewController = toVC;
// I checked here toVC has a parentViewController set to ContainerViewController
}
SettingsViewController shows up
On Pressing the "Main" Button on SettingsViewController
IBACtion in SettingsMainController is called
- (IBAction)onMain:(id)sender {
if ([self parentViewController]) { // parentViewController is nil here
[(ContainerViewController*)[self parentViewController] showViewControllerWithName:@"root"];
}
}
But ParentViewController is nil here and hence nothing is shown. The SettingsViewController is toVC from the function call showViewControllerWithName
in the previous step.
Somewhere between showViewControllerWithName()
and OnMain()
, parentViewController
is being set to nil
. I checked till viewDidAppear and parentViewController is not nil until that point.
My Questions are
parentViewController
being set to nil?viewDidAppear
I am unable to fix this. I tried a very hacky way where i keep track of the parent in the derived class even then transitionFromViewController:
throws an exception saying both view controllers should have same parent.
I am stuck at this for almost two days now. I Would really appreciate some help.
Well I finally was able to make it work . Let me concisely explain the question again
->ContainerViewController
presents MainViewController
and when you check MainViewController.ParentController, it is infact ContainerViewController
->ContainerViewController
transitions from MainViewController
to SettingsViewController
using the following function
(void) showViewControllerWithName:(NSString*)vctype
{
UIViewController * toVC = [ViewControllerFactory getViewControllerOfType:vctype];
toVC.view.frame = containerView.bounds;
toVC.view.autoresizingMask = containerView.autoresizingMask;
[currentSubViewController willMoveToParentViewController:nil];
[self addChildViewController:toVC];
[self transitionFromViewController:currentSubViewController
toViewController:toVC duration:1.0 options:UIViewAnimationOptionCurveLinear animations:^{} completion:^(BOOL finished){
[currentSubViewController removeFromParentViewController];
[toVC didMoveToParentViewController:self];
}];
currentSubViewController = toVC;
}
->After the transition SettingsViewController.parentViewController
is nil
Following is the fix :
animations:^{} completion:^(BOOL finished){
[currentSubViewController removeFromParentViewController];
[toVC didMoveToParentViewController:self];
}];
currentSubViewController = toVC;
is changed to
animations:^{} completion:^(BOOL finished){
}];
[currentSubViewController removeFromParentViewController];
[toVC didMoveToParentViewController:self];
currentSubViewController = toVC;
And now SettingsViewController
has a parent.
Well, If anyone could explain what exactly is going on then it would be great.