Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make hide/unhide master view controller work in landscape the same as portrait

I am using a split view controller in a simple app. Leaving everything as default works fine. In other words, the master view controller always shows in landscape and overlays the detail view controller in portrait when the back button is pressed.

What I wanted to do was make the master view controller mimic the same functionality in landscape as it does in portrait. In other words, when the device is in landscape, I want the master view controller to be hidden until I hit the back button and then I want it to overlay the detail view controller.

I figured the best way to do this was to use the following code:

 - (BOOL)splitViewController:(UISplitViewController *)svc shouldHideViewController:     (UIViewController *)vc inOrientation:(UIInterfaceOrientation)orientation
 {
     return self.bHideMaster;
 }

This worked in that it hid the master view controller in landscape mode. I then used the following code to make it reappear:

 - (void)hideUnhidePagesController:(id)sender
 {
     [UIView beginAnimations:nil context:NULL];
     [UIView setAnimationDuration:0.30f];

     UISplitViewController* spv = self.splitViewController;

     // Change hide to unhide or vica versa
     self.bHideMaster= !self.bHideMaster;

     // Hide the button if master is visible
     if(self.bHideMaster)
     {
         self.navigationItem.leftBarButtonItem = self.pagesBarButton;
     }
     else
     {
          self.navigationItem.leftBarButtonItem = nil;
     }

     [spv.view setNeedsLayout];
     [spv willRotateToInterfaceOrientation:self.interfaceOrientation duration:0];
     [[self.splitViewController.viewControllers lastObject] view].frame = self.splitViewController.view.frame;
     [UIView commitAnimations];
 }

This ALMOST worked. I have 2 problems:

  1. The transition from hide-to-unhide and unhide-to-hide the master view controller isn't animated and is much to stark. I added animation code (see above) but it only animates the detail view controller and not the master view controller. The master appears and dis-appears instantly (leaving a black box on disappear) until the detail view controller slides over.

  2. This also shows my second problem. I want the master view controller to overlap the detail view controller when it appears in landscape mode, leaving the detail view controller as is. Instead, it resizes the detail view controller (the same way it does in landscape mode before I started). I want the master view controller to interact the same way it does in portrait mode: Master slides in over the top of the detail controller and slides back out when it an item is selected.

If I could solve problem 2, then I don't have to worry about problem 1. It seems like there should be a method in the split view controller that would slide in the master from the left (overlapping the detail view controller). It does it in portrait mode so the code must be there. How can I call that same code in landscape mode?

Thanks!

---------EDIT 1---------

I have refactored hideUnhidePagesController and am getting closer. The window now overlays in both portrait and landscape. There is still a problem if the master is visible on rotation. It gets confused and inverts the expected behavior. I'm working on it. Here the amended code:

 - (void)hideUnhidePagesController:(id)sender
{
    // Change hide to unhide or vica versa
    self.bMasterIsHidden= !self.bMasterIsHidden;

    NSArray *controllers = self.splitViewController.viewControllers;
    UIViewController *rootViewController = [controllers objectAtIndex:0];
    UIView *rootView = rootViewController.view;
    CGRect rootFrame = rootView.frame;
    if(self.bMasterIsHidden)
    {
        rootFrame.origin.x -= rootFrame.size.width;
    }
    else
    {
        rootFrame.origin.x += rootFrame.size.width;
    }
    [UIView beginAnimations:@"hideUnhideView" context:NULL];
    rootView.frame = rootFrame;
    [UIView commitAnimations];
 }
like image 710
JustLearningAgain Avatar asked May 03 '13 06:05

JustLearningAgain


2 Answers

In ios 8.0

self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModePrimaryHidden;

to hide master view

like image 118
sschunara Avatar answered Oct 16 '22 08:10

sschunara


To get the effect you describe I had to add the following code to my DetailViewController.

- (BOOL)splitViewController:(UISplitViewController *)svc shouldHideViewController:
(UIViewController *)vc inOrientation:(UIInterfaceOrientation)orientation
{
    return YES;
}

Then my split view works the same in portrait and landscape mode.

like image 45
Kyle Nunery Avatar answered Oct 16 '22 08:10

Kyle Nunery