Calling setView on a UIViewController removes the current view from its superview automatically. I couldn't find this documented. In my case I want to dynamically swap a UIViewController object for another while maintaining my view structure. I was planning to just relink the view to the new controller but alas, that doesn't work.
In general, automatically removing the view from its superview seems like a sensible decision. The documentation should reflect this though.
(For anyone thinking it's a really bad idea to swap a view controller object in this way, let me add that the controller I'm swapping in is a subclass of the existing controller. And this method is great for adding functionality to a view that is an extension of another.)
This is how I solved it:
UIView *viewToKeep = self.viewController.view; UIView *superview = viewToKeep.superview; self.viewController.view = nil; // removes the view from its superview UIViewController *swapInViewController = [[UIViewController alloc] init]; swapInViewController.view = viewToKeep; [superview addSubview: viewToKeep]; [viewToKeep applyConstraintsToFillSuperview]; // a helper to add auto layout constraints that make the view always fill it's parent self.viewController = swapInViewController;