UISplitViewController: How force to show master popover in app launch? (portrait)

25,640

Solution 1

I struggled with this one for a while, and even now I'm not 100% happy with the solution, but it is the only thing I've been able to come up with, given the current constraints.

First, override the following delegate method:

- (void)splitViewController:(UISplitViewController *)splitController willHideViewController:(UIViewController *)viewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController:(UIPopoverController *)popoverController

and use it to grab a reference to the bar button item, and store it in an iVar:

barButtonForMaster = barButtonItem;

Then, when you want to show the master view controller, make a call like this:

[barButtonForMaster.target performSelector: barButtonForMaster.action withObject: barButtonForMaster];

In case you want to perform this right at the start, then use some delay in order to prevent app crashing (thanks to the helpful comment):

[barButtonForMaster.target performSelector: barButtonForMaster.action withObject: barButtonForMaster afterDelay:1];

In that case you can perform the selector right in the split view delegate method.

Solution 2

No suggestion here for 5.1, but one for 8.0:

Now with iOS8, there are a bunch of new methods for UISplitViewController configuration.

In your case, juste set the right value in preferredDisplayMode, for example in the masterViewController viewDidLoad.

Objective-C:

- (void)viewDidLoad {
    // configuring splitviewcontroller
    self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModeAllVisible;

    //....
}

Swift:

    override func viewDidLoad() {
        self.splitViewController?.preferredDisplayMode = UISplitViewControllerDisplayMode.AllVisible
    }

But it's of course iOS8 only.

Solution 3

Extending on Rob's answer, this works well for me (in viewDidLoad of detail screen):

//If in portrait mode, display the master view
if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation)) {
    [self.navigationItem.leftBarButtonItem.target performSelector:self.navigationItem.leftBarButtonItem.action withObject:self.navigationItem];
}

No need to fetch a separate reference, using self.navigationItem.leftBarButtonItem instead

Solution 4

For iOS8 the easiest way is with the following:

 self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModePrimaryOverlay;

I use this when the app is launched the first time for showing log-in in masterViewController. In all other cases I use

self.splitViewController.preferredDisplayMode = UISplitViewControllerDisplayModeAutomatic

Solution 5

If you need it at app launch, override this method in your detail view controller:

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

However if you then need it to subsequently hide it looks as though the method isn't called, so you'll have to manually hide it.

Share:
25,640

Related videos on Youtube

alejandromp
Author by

alejandromp

Updated on July 09, 2022

Comments

  • alejandromp
    alejandromp almost 2 years

    In an iPad App i'm using the UISplitViewController. I need to force to show the master popover when the app launch in portrait mode.

    Now I'm using this code and it works well on iOS 5.0.

    if (UIInterfaceOrientationIsPortrait(self.interfaceOrientation)) {
       if ([[[AppDelegate sharedAppDelegate] splitViewController] respondsToSelector:[[[AppDelegate sharedAppDelegate] btnMenu] action]]) {
          [[[AppDelegate sharedAppDelegate] splitViewController] performSelector:[[[AppDelegate sharedAppDelegate] btnMenu] action]];
       }            
    }
    

    But in iOS 5.1 (with the new type of master popover) the behaviour seems to be random. Sometimes the popover shows in fullscreen and sometimes works well.

    Some suggestion for 5.1?

  • alejandromp
    alejandromp almost 12 years
    Thanks. I do this with your code plus my previous code. But sometimes the App crashes. I think that is because I do that in the splitViewController delegate and maybe, in some cases, the controller it's not fully created. Now I do that code with perfromSelectorAfterDelay and work very well. Thanks.
  • BObereder
    BObereder about 11 years
    this is amazing and works perfectly! it is giving me a warning though, "PerformSelector may cause a leak because its selector is unknown" would you know why and what to do about it?
  • Setomidor
    Setomidor about 11 years
    AFAIK the compiler analyzes method calls and adds code to manage the ARC reference counters (to managage Garbage Collection). Calling a method like this is kind of like using reflections in Java (done during runtime), so the compiler cannot do its refCount magic in this case. However, as long as the method called does not return any allocated object (which would then be a leak) it won't be any problem. In this case, we're not returning anything from the called method. To avoid this warning, see: learningipadprogramming.com/2012/04/03/…
  • anders
    anders over 10 years
    This will result in a compiler possible memory leak warning
  • Victor Engel
    Victor Engel over 9 years
    That toggleMasterVisible is a private method.
  • Victor Engel
    Victor Engel over 9 years
    This doesn't work if nothing is loaded in the detail view controller, which would be the main point to force the master to show.
  • Setomidor
    Setomidor over 9 years
    @VictorEngel it does, but since this code goes into the detail view you need to make sure to load an empty detail view by default.
  • phatmann
    phatmann over 9 years
    This forces side-by-side display. It does not show the master view in popover mode as the OP requested.
  • phatmann
    phatmann over 9 years
    This is deprecated in iOS 8.
  • Martin
    Martin almost 9 years
    @phatmann, I don't think alejandromp was talking about popover. He says I need to force to show the master popover but that doesn't mean anything, in fact. Considering the context, he does talk about displaying the master view side by side in portrait mode, as in landscape.
  • fujianjin6471
    fujianjin6471 over 6 years
    can also be called in detailViewController