Search code examples
ioshideuisplitviewcontroller

UISplitViewController doesn't hide masterViewController in landscape mode


NOTE: Before reading this question please note that I have read the previous questions that explain the deficiencies regarding apple's implementation of UISplitViewController and how I should use the open-sourced "MGSplitViewController" because its not too easy to simply hide the master view controller on a split view controller in landscape-mode. Please keep in my mind that I'm limited to using the normal UISplitViewController in iOS 5.1.

Now onto the question:

I have a split view controller with table views on the left side (master view) and a detail view controller on the right. I'm using a navigation controller to control the left side which is a table view that transitions onto another table view ("DataTableViewController"). In order to hide this left side, I have placed a "hide" button on the navigation tool bar of the detail view controller. When the hide button is pressed, I change my "_hideMaster" property:

-(IBAction)hidePressed
{
    _hideMaster = !_hideMaster;
    // Must manually reset the delegate back to self in order to force call "shouldHideViewController"
    self.splitViewController.delegate = nil;
    self.spliteViewController.delegate = self;

}

and then automatically this method is called in the SplitViewController delegate:

// This is called when I change the delegate from nil back to self.
- (BOOL)splitViewController: (UISplitViewController*)svc shouldHideViewController: (UIViewController *)vc inOrientation:(UIInterfaceOrientation)orientation 
{
    return _hideMaster;
}

When I debug it, I can see that everything goes according to plan and the property has the correct value when it enters the method splitViewController:shouldHideViewController:inOrientation:

The only problem is that nothing happens. My left most table view (DataTableViewController) does not disappear. When I look closer, the (UIViewController *)vc parameter in the delegate method is not the table view controller that I want to hide but instead the navigation controller associated with this table view. So essentially it is trying to hide the navigation controller - which is clearly not what I want...

How can I make it so that the UIViewController parameter in the automatically called delegate method (shouldHideViewController:) calls the topmost view controller associated with that navigation controller? (After all, I want to hide DataTableViewController)


Solution

  • Here's how I handle it. Might need more work for making the MasterViewController reappear if it is not instantiated on the way back.

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.30f];
    [[self.splitViewController.viewControllers lastObject] view].frame = self.splitViewController.view.frame;
    [UIView commitAnimations];