Question

I have a root view controller with subview to be wrappers for views of child view controllers. The basic idea is my root controller has a left and right view controller, both present on screen (similar to a splitviewcontroller). On load a modal view pops up over the root view controller and asks for details. The modal view then contacts a server, and is dismissed after getting a response. The root controller then adds the child view controllers with the following code:

[self addViewController:self.leftViewController];
[self addViewController:self.rightViewController];

[self addView:self.rightViewController.view ToWrapper:self.rightViewWrapper];
[self addView:self.leftViewController.view ToWrapper:self.leftViewWrapper];

Where add view controller is:

[self addChildViewController:controller];
[controller didMoveToParentViewController:self];

and addViewToWrapper just adds the view controller's view to the relevant subview of the rootViewController as follows:

[[viewWrapper.contentView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];
newSubview.frame = viewWrapper.contentView.bounds;
newSubview.autoresizingMask = UIViewAutoresizingFlexibleHeight |    UIViewAutoresizingFlexibleWidth;
[viewWrapper.contentView addSubview:newSubview];

99% of the time this works fine. Both views appear instantly and viewWillAppear fires in both child controllers. However, occasionally the screen stays white for a brief period and viewWillAppear doesn't fire in the right view controller (EDIT: and the left). All of the other view lifecycle methods fire, just not viewWillAppear.

Unfortunately, I can't give code for the whole class as it is complex and proprietary. But are there any clues in this description for this intermittent behaviour?

Was it helpful?

Solution

Some thoughts on this:

ONE

It looks like your containment methods are not being called properly. They should look like this for each viewController:

    [self addChildViewController:controller];
    [self.view addSubview:controller.view]; 
    [controller didMoveToParentViewController:self];

The view should be added to the superview in between the addChild and didMove calls.

TWO

To my knowledge, there cannot be more than one presentation or dismissal occurring at a time. I.e. If you are trying to present (add) your child viewControllers at the same time as the modal is being dismissed, you will see an error in the console log and your "add" operation will not occur.

My recommendation would be to create a delegate protocol on the modal viewcontroller. And in the completion block of dismissViewControllerAnimated:completion:, call your delegate method:

[self dismissViewControllerAnimated:YES completion:^{
   if ([weakSelf.delegate respondsToSelector:@selector(settingsViewControllerDidDismiss:)])
   {
       [weakSelf.delegate settingsViewControllerDidDismiss:self];
   }
}];

And in your rootViewController, you would begin adding its children inside of settingsViewControllerDidDismiss or whatever you decide to call that method. The point is that the "add" operation begins AFTER the dismissal operation.

Hope this helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top