Reputation: 13887
I have a view controller hierarchy:
UIViewController
: A with an embedded child UIPageViewController
. A overlays various stuff on top of B and tinkers with the navigation, and other stuff.UIPageViewController
: B.When A is instantiated, B is embedded in it. My override of prepareForSegue:sender
in A causes C to be instantiated and set as B's current page:
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([[segue identifier] isEqualToString: @"EmbedPagesSegue"])
{
UIPageViewController *const pagesViewController = [segue destinationViewController];
[pagesViewController setDataSource: self];
[pagesViewController setDelegate: self];
[self setPagesViewController: pagesViewController];
UIViewController *const initialPage = [self initialDisplayedPage];
[pagesViewController
setViewControllers: @[initialPage]
direction: UIPageViewControllerNavigationDirectionForward
animated: NO
completion:nil];
// Point X.
// Segue not yet started.
// A is not on screen yet!
// C has already been added to B
}
}
C overrides viewDidAppearAnimated:
.
When the initial page is presented, C's viewDidAppearAnimated:
is called at Point X, before C's view can be on screen because B has yet to be added to A (the segue is just setting up).
This is a problem because C's implementations of viewDidAppearAnimated:
needs to be able to reference the A that it has appeared in.
For subsequent pages, the embedding segue has completed, so B is added to A, and is on screen. In these cases the viewDidAppearAnimated:
call to C is appropriate.
viewDidAppearAnimated:
should actually be called viewDidAppearAnimatedInParentButTheParentMightNotHaveAppearedYet:
Is there a clean way for C to access A during this initial set up process? I could do some kind of hack like defer the setup with performSelectorOnMainThread:withObject:waitUntilDone:
, but I'd rather not.
Am I implementing the embedding segue in the wrong way?
Is this just a bad design – in which case, what instead?
Any other suggestions?
Upvotes: 0
Views: 379
Reputation: 57060
Usually, it is a bad design to make assumptions about the view or controller hierarchy above the point you are at. So making assumptions about parent view controllers or superviews is normally not recommended. In your case, if you need to access A from C, create public API in C where you can pass A in some form (most likely, weak
ly), so it can configure itself.
Upvotes: 1