This question has been asked a lot e.g. here but as far as I can see is yet to be answered in full.
I have a UITabBarController
with a UINavigatio
Tim Arnold's response worked great for me, thanks!
One trap to watch out for: your modal page-curl transition will take over the whole screen if your content view controller is added as a child of the container view controller. You could just not add it as a child, but then none of the view lifecycle methods will get called on your content controller (e.g. viewDidLoad
, viewWillAppear
), which could be a problem.
Fortunately, there is a way around this. In your container controller:
viewDidLoad
viewDidAppear
viewWillDisappear
.That way, your content controller gets its lifecycle methods called, while still being able to do a modal page-curl transition without taking up the whole screen.
Here is the entire code of a bare-bones solution:
@interface XXContainerController : UIViewController
@property (strong, nonatomic) UIViewController *contentController;
@property (nonatomic) BOOL curled;
@end
@implementation XXContainerController
@synthesize contentController = _contentController;
@synthesize curled = _curled;
- (void)viewDidLoad
{
[super viewDidLoad];
self.contentController = [self.storyboard
instantiateViewControllerWithIdentifier:@"SomeControllerInStoryboard"];
// Add content controller as child view controller.
// This way, it will receive all the view lifecycle events
[self addChildViewController:self.contentController];
self.contentController.view.frame = self.view.bounds;
[self.view addSubview:self.contentController.view];
[self.contentController didMoveToParentViewController:self];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
// Remove the content controller as child view controller.
// This way, the modal page curl transition will
// not take over the whole screen.
// NOTE: need to wait until content controller has appeared
// (which will happen later).
// Achieve this by running the code at the end of the animation loop
[UIView animateWithDuration:0 animations:nil completion:^(BOOL finished) {
[self.contentController removeFromParentViewController];
}];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
// Add the content controller as child view controller again
// so it receives the view lifecycle events
[self addChildViewController:self.contentController];
}
- (void)setCurled:(BOOL)curled
{
if (curled == _curled) return;
_curled = curled;
// Curl up the content view and show underneath controller's view
if (curled) {
// Note you can specify any modal transition in storyboard
// E.g. page curl, flip horizontal
[self.contentController
performSegueWithIdentifier:@"SomeModalSegueDefinedInStoryboard"
sender:self];
// Uncurl and show the content controller's view again
} else {
[self.contentController dismissModalViewControllerAnimated:YES];
// Have to do this, otherwise the content controller's view
// gets messed up for some reason
self.contentController.view.frame = self.view.bounds;
}
}
@end