Search code examples
iosiphoneswiftipaduisplitviewcontroller

Force UISplitViewController to always show master (only) in landscape (on iPhone 6 Plus)


In a Universal App I can't find a way to always show (and only) the master controller, even on iPhone 6 Plus in landscape rotation.

What I want to achieve is to see UISplitViewController in action only on the iPad and NOT on the iPhone, don't know if it's possible

delegate methods doesn't help:

func splitViewController(svc: UISplitViewController, shouldHideViewController vc: UIViewController, inOrientation orientation: UIInterfaceOrientation) -> Bool {
        return false
    }

    func splitViewController(splitViewController: UISplitViewController, collapseSecondaryViewController secondaryViewController: UIViewController, ontoPrimaryViewController primaryViewController: UIViewController) -> Bool {
        return true
    }

Solution

  • You need to override the trait collection of your UISplitViewController to always have a compact size class. To do so you need to insert a container view controller as the parent of your UISplitViewController:

    1. Embed your UISplitViewController into a ContainerViewController
    2. Add the following code into your container view controller subclass to override the trait collection of your child view controller:

      class ContainerVC: UIViewController {
      override func viewDidLoad() {
          super.viewDidLoad()
      }
      
      override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
          performOverrideTraitCollection()
      }
      
      private func performOverrideTraitCollection() {
          for childVC in self.childViewControllers {
              setOverrideTraitCollection(UITraitCollection(horizontalSizeClass: .Compact), forChildViewController: childVC)
          }
      }}
      

    Great explanation in Building Adaptive Apps with UIKit (WWDC 2014)