I’m trying to have something similar to a UINavigationController so I can customize the animations. To start, I’m just using Apple stock animations. Here’s my containerViewController:
- (void)loadView {
// Set up content view
CGRect frame = [[UIScreen mainScreen] bounds];
_containerView = [[UIView alloc] initWithFrame:frame];
_containerView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
self.view = _containerView;
}
- (id)initWithInitialViewController:(UIViewController *)vc {
self = [super init];
if (self) {
_currentViewController = vc;
[self addChildViewController:_currentViewController];
[self.view addSubview:_currentViewController.view];
[self didMoveToParentViewController:self];
_subViewControllers = [[NSMutableArray alloc] initWithObjects:_currentViewController, nil];
}
return self;
}
- (void)pushChildViewController:(UIViewController *)vc animation:(UIViewAnimationOptions)animation {
vc.view.frame = _containerView.frame;
[self addChildViewController:vc];
[self transitionFromViewController:_currentViewController toViewController:vc duration:0.3 options:animation animations:^{
}completion:^(BOOL finished) {
[self.view addSubview:vc.view];
[vc didMoveToParentViewController:self];
[self.subViewControllers addObject:vc];
}];
}
- (void)popChildViewController:(UIViewController *)vc WithAnimation:(UIViewAnimationOptions)animation {
// Check that there is a view controller to pop to
if ([self.subViewControllers count] <= 0) {
return;
}
NSInteger idx = [self.subViewControllers count] - 1;
UIViewController *toViewController = [_subViewControllers objectAtIndex:idx];
[vc willMoveToParentViewController:nil];
[self transitionFromViewController:vc toViewController:toViewController duration:0.3 options:animation animations:^{
}completion:^(BOOL finished) {
[vc.view removeFromSuperview];
[vc removeFromParentViewController];
[self didMoveToParentViewController:toViewController];
[self.subViewControllers removeObjectAtIndex:idx];
}];
}
I have this ContainerViewcontroller as my rootViewController of the window. I can add my initial viewController and push a view controller. When I try to pop though, I get
ContainerViewController[65240:c07] Unbalanced calls to begin/end appearance transitions for <SecondViewController: 0x8072130>.
I’m wondering what I am doing wrong. I figured my initialViewController is still underneath the secondViewController. Any thoughts? Thanks!
I don’t know if this is what’s causing your problem, but shouldn’t this:
be:
Also, I’m not sure what you’re doing with the subViewControllers array. It seems to be a duplication of the childViewControllers array that is already a property of a UIViewController.
One other thing I’m not sure is right. In your pop method your toViewController is the last controller in the _subViewControllers array. Don’t you want it to be the second to last? Shouldn’t the last be the one you’re popping? You’re popping vc, which is a controller you’re passing in to the method, I don’t understand that.
This is the way I’ve made a navigation like controller. In its containment behavior, it acts like a navigation controller, but without a navigation bar, and allows for different transition animations:
After Edit: I was able to duplicate the back button function with this controller by adding a navigation bar to all my controllers in IB (including in the one that is the custom container controller). I added a bar button to any controllers that will be pushed, and set their titles to nil (I got some glitches if I left the title as “item”). Deleting that title makes the button disappear (in IB) but you can still make connections to it in the scene list. I added an IBOutlet to it, and added this code to get the function I wanted:
I’ve shown two different ways that worked to access a title — in IB you can set a title for the controller which I used in the else clause, or you can use the navigationItem title as I did in the if part of the clause. The “-3” in the else clause is necessary because at the time viewWillAppear is called, the controller that is being popped is still in the childViewControllers array.