Wednesday, June 29, 2016

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

1 comment

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?

1 Answers

Answers 1

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.

If You Enjoyed This, Take 5 Seconds To Share It

1 comment:

  1. If you are interested in earning money from your traffic by running popup advertisments - you should run with one of the most established networks: Propeller Ads.

    ReplyDelete