Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can I not place Master and Detail view next to each other in UISplitViewController on the first run, but upon rotation it works?

I have a split view controller that has a list of items on the left and a detail view on the right. Relevant code in AppDelegate:

let splitViewController = mainView.instantiateViewControllerWithIdentifier("initial") as! UISplitViewController



        let rightNavController = splitViewController.viewControllers.last as! UINavigationController
        let detailViewController = rightNavController.topViewController as! DetailsIpad

        let leftNavController = splitViewController.viewControllers.first as! UINavigationController
        let masterViewController = leftNavController.topViewController as! MainViewController

        masterSplitViewController = masterViewController
        detailSplitViewController = detailViewController

        // Override point for customization after application launch.
        let navigationController = splitViewController.viewControllers[splitViewController.viewControllers.count-1] as! UINavigationController
        navigationController.topViewController!.navigationItem.leftBarButtonItem = splitViewController.displayModeButtonItem()
        splitViewController.delegate = self

        self.window!.rootViewController = splitViewController

When I first launch the app I see that the right part of the split screen takes up all of the screen:

enter image description here

If I rotate the screen, it becomes properly set (probably because both views are present on the screen):

enter image description here

When I set breakpoints everywhere, I see that the detail view on the right gets loaded before the master view on the left (list of items), despite not being called directly. I cannot change the order in which the views of the split screen are called. How can I fix this?

UPDATE:

I am able to set this before showing split view controller:

splitViewController.preferredDisplayMode = UISplitViewControllerDisplayMode.AllVisible

And in the ViewDidLoad of the split controller when I am printing it:

print(self.preferredDisplayMode.rawValue)

I get: 2, which is AllVisible. But still result is the same.

like image 718
Async- Avatar asked Jun 09 '16 13:06

Async-


1 Answers

It's the default behavior of UISplitViewController. Have a close look at the following-

// An animatable property that controls how the primary view controller is hidden and displayed. A value of `UISplitViewControllerDisplayModeAutomatic` specifies the default behavior split view controller, which on an iPad, corresponds to an overlay mode in portrait and a side-by-side mode in landscape.
@property (nonatomic) UISplitViewControllerDisplayMode preferredDisplayMode NS_AVAILABLE_IOS(8_0);

Here's the key part from same definition-

on an iPad, corresponds to an overlay mode in portrait and a side-by-side mode in landscape.

Also, if you want to query the current state (display mode) of a UISplitViewController you should use this property-

// The actual current displayMode of the split view controller. This will never return `UISplitViewControllerDisplayModeAutomatic`.
@property (nonatomic, readonly) UISplitViewControllerDisplayMode displayMode NS_AVAILABLE_IOS(8_0);

And remember, you can't compare this with UISplitViewControllerDisplayModeAutomatic because-

This will never return UISplitViewControllerDisplayModeAutomatic.

My suggestion would be to set preferredDisplayMode to the value you want. In your case, it seems like you need the primary (master) to always be visible. So here's the proposed solution-

mySplitVC.preferredDisplayMode = UISplitViewControllerDisplayModeAllVisible

Why it loads the secondary(detail) controller first?

As you can see, a UISplitViewController instance always needs a detail view no matter what displayMode it is in currently. So it's a good call to

  • load the detail view first.
  • load the primary view after (conditionally based on displayMode).

Hope this helps.

like image 98
Tarun Tyagi Avatar answered Nov 15 '22 19:11

Tarun Tyagi