7

I have a simple iPad app with MasterviewController with a tableview and and a DetailViewController containing a UIWebView. Then i dragged and dropped a SplitViewController in my Storyboard, connected it with my Master and Detail controllers. In MasterViewController i am using the following:

- (void) awakeFromNib
{
    self.splitViewController.delegate = self;
}

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

It currently looks like the following:

enter image description here

Everything is working great. What i want to do is to hide and unhide the MasterViewController with a button at the top left side of DetailViewController, just like the iPad Mail app.

I have found some questions related to this problem but they are not creating the SplitView as simply as i am by just dragging it in the Storyboard and writing few lines of code, So don't mark it as duplicate or something like that.

NOTE: Kindly do not suggest using MGSplitViewController or any other third party library. Thanks in advance.

The MasterViewController is embedded inside a navigation controller. While DetailViewController has a top bar manually added on it because it looses the navigation bar at top when the whole things is added in the SplitView. What i know is that i can create an IBAction button on the top bar of DetailView but dont know how to trigger the hide and unhide functionality.

Jessica
  • 1,508
  • 15
  • 25

1 Answers1

4

I do it like this in the master view controller (TableController):

#import "TableController.h"
#import "ViewController.h"

@interface TableController ()

@property (strong, nonatomic) NSArray * theData;
@property (strong, nonatomic) UIViewController * detailVC;

@end

@implementation TableController 


-(void)awakeFromNib {
   self.splitViewController.delegate = self;
   self.detailVC = self.splitViewController.viewControllers[1];
}

-(void)splitViewController:(UISplitViewController *)svc willShowViewController:(UIViewController *)aViewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem {
    NSMutableArray *itemArray = [self.detailVC.toolBar.items mutableCopy];
    [itemArray removeObject:barButtonItem];
    [self.detailVC.toolBar setItems:itemArray];
}


-(void)splitViewController:(UISplitViewController *)svc willHideViewController:(UIViewController *)aViewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController:(UIPopoverController *)pc {
    barButtonItem.title = @"Master";
    NSMutableArray *itemArray = [self.detailVC.toolBar.items mutableCopy];
    if (! itemArray) {
        itemArray = [NSMutableArray arrayWithObject:barButtonItem];
    }else{
        [itemArray insertObject:barButtonItem atIndex:0];
    }
    [self.detailVC.toolBar setItems:itemArray];
}

I added a tool bar in IB to the detail controller, and gave it the IBOutlet, toolBar.

Q8i
  • 1,767
  • 17
  • 25
rdelmar
  • 103,982
  • 12
  • 207
  • 218
  • @Jessica,How is it not working? Do you get errors, or do you just get nothing happening? – rdelmar Apr 29 '13 at 15:01
  • @Jessica, Well, this is the pretty standard way to add this behavior. You should do some logging to see why this doesn't work. Check to see that none of the objects (self.splitViewController, self.detailVC, self.detailVC.toolBar,etc.) are not nil. – rdelmar Apr 29 '13 at 15:06
  • @Jessica, I see several things that you did differently from me. You're using a navigation bar instead of a tool bar which would require different code. Is there a reason you don't want to use a tool bar? Second, you commented out the line where I define detailVC. When the app starts detailVC already exists, you don't need to segue to it, so what you're doing with that replace segue isn't right. Also the fact that you are returning NO from the shouldHideViewController:inOrientation: method keeps those 2 delegate methods I use from being called. Do you want the master to show in portrait? – rdelmar Apr 30 '13 at 18:12
  • @Jessica, I don't know if there's a way to do that with UISplitViewController. The only way I know to show and hide the master view is with those two delegate methods, and they won't be called if you return NO for shouldHideViewController:inOrientation: (which you have to do to have the master show up in portrait). I'll have to think about this some more. It could be done with a custom container controller which you could make look like a split view controller. – rdelmar Apr 30 '13 at 21:40
  • @Jessica, Yeah, the way he's doing it pretty much makes the split view controller superfluous. He's just removing it, and then adding the detail controller's view as the subview of the window. IT doesn't seem to handle rotations at all -- I tried modifying it so it would, but got weird results. – rdelmar May 01 '13 at 00:59
  • @Jessica, just to show you what I meant by using custom a container controller, here is a link to a simple project that does what I think you want. https://jumpshare.com/b/KGT7Ti203UDJ4SST6gKv – rdelmar May 01 '13 at 02:10
  • yes thats exactly what i wanted. 1) Is this the only way to implement this behaviour, i mean can we do it with splitviewcontrollers without having to introduce containers? 2) I am not able to understand how you are using NSLayoutConstraint *LeftCon IBOutLet and where it is connected in the Storyboard. Check this https://jumpshare.com/b/MOHB5bkeysjX0ovwgJnT – Jessica May 01 '13 at 15:35
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/29252/discussion-between-rdelmar-and-jessica) – rdelmar May 01 '13 at 15:45
  • @Jessica, join me in the chat room, it will be easier to discuss this there. – rdelmar May 01 '13 at 18:11
  • I was unable to pass data between the Master and Detail. Tried both with PrepareForSegue and DidSelectRow methods but its not working – Jessica May 01 '13 at 23:47
  • @Jessica, master and detail are both child view controllers of the splitLikeController, so you should be able to get a reference from one to the other like (from the master controller): DetailController *detailVC = self.parentViewController.childViewControllers[1] – rdelmar May 02 '13 at 00:31
  • @Jessica, one correction to my last post. The master controller isn't a direct child controller of the splitLikeController, the navigation controller it's embedded in is the child. The master controller would be the navigation controller's topViewController. – rdelmar May 02 '13 at 00:37
  • It just gets crashed may be because the project i am working on has the splitviewcontroller inside another controller. Plus with the containers, replace segue has to be removed that leaves no option – Jessica May 03 '13 at 22:24
  • @Jessica, there's always an option. I'm not sure why you even needed the replace segue -- can't you just update the UI in the detail controller when you select a new row, rather than replacing the controller? Also, there's no reason that it should crash if the splitLikeController is inside another controller. I've made a project like that before. – rdelmar May 03 '13 at 22:45
  • Can you take a look into this question: http://stackoverflow.com/questions/18935821/ios-7-uitoolbar-overriding-with-status-bar/ It splitview like controller was made using the containers just like you told in the answer but the toolbar is colliding with the status bar. Kindly take a look. Thanks! – Jessica Sep 21 '13 at 21:47
  • @Jessica, I posted an answer on that question. – rdelmar Sep 22 '13 at 00:16