I have the following code to adopt a child view controller into a parent:
public static void AdoptViewController(this UIViewController parent, UIViewController child)
{
parent.AddChildViewController(child);
parent.View.AddSubview(child.View);
child.DidMoveToParentViewController(parent);
}
This mostly works fine, except when the parent view is already visible. In such cases, the child view controller does not receive a ViewWillAppear event. This is causing knock-on problems throughout my app.
I found this post, which suggests doing this:
public static void AdoptViewController(this UIViewController parent, UIViewController child)
{
parent.AddChildViewController(child);
child.BeginAppearanceTransition(true, false);
parent.View.AddSubview(child.View);
child.EndAppearanceTransition();
child.DidMoveToParentViewController(parent);
}
However, that causes the ViewWillAppear event to be raised twice in the case where the parent is not yet visible. I re-worked the code a bit to this:
public static void AdoptViewController(this UIViewController parent, UIViewController child)
{
parent.AddChildViewController(child);
// could also use ViewIfLoaded for later iOS versions
var parentAlreadyVisible = parent.IsViewLoaded && parent.Window != null;
if (parentAlreadyVisible)
{
child.BeginAppearanceTransition(true, false);
}
parent.View.AddSubview(child.View);
if (parentAlreadyVisible)
{
child.EndAppearanceTransition();
}
child.DidMoveToParentViewController(parent);
}
This appears to work mostly fine, except now my ViewDidAppear event is firing twice in the child view! The first time it is triggered by EndAppearanceTransition, and the second time appears to originate from iOS itself. This isn't actually causing me any problems, but it is disconcerting nonetheless.
How do I write a standalone AdoptViewController utility method that correctly adopts a child view controller into a parent, and raises the right events the right number of times?