22

I'm building a universal app using UISplitViewController and targeting iOS 9 and above. The app language is Objective-C.

Having started with the Xcode Master/Detail template and set up my views in the standard way, I'm realising that the app will be better if I keep the master view on screen at all times (on iPad), including when the device is in portrait mode. However, no matter how hard I search, I can't find anything to help me learn how this is achieved. I know this was previously achieved using splitViewController:shouldHideViewController:inOrientation:

However, this method is deprecated in iOS 9 and I can't figure out what replaces it and why. I've looked at the new delegate methods for UISplitViewController and find them completely lacking in any level of intuitiveness.

I'd really appreciate some pointers in regard to what replaces splitViewController:shouldHideViewController:inOrientation: and how it can be used to keep the master view displayed at all times on the iPad.

beev
  • 1,197
  • 2
  • 16
  • 33

2 Answers2

37

Subclass UISplitViewController

There is no need to specifically track orientation changes: Master and Detail will still be displayed in sequence on iPhone in portrait mode, and most iPhone in landscape mode.
preferredDisplayMode:.allVisible only affects the modes where both views can be simultaneously visible.

Swift

class SplitViewController: UISplitViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        preferredDisplayMode = .allVisible
    }
}

Obj-C

- (void)viewDidLoad {
    [super viewDidLoad];
    self.preferredDisplayMode = UISplitViewControllerDisplayModeAllVisible;

}

iPad Portrait & iPhone 8 Plus Landscape

enter image description here

Community
  • 1
  • 1
SwiftArchitect
  • 47,376
  • 28
  • 140
  • 179
  • Superb, thanks. Will try it out. But is it really necessary to subclass just to change this one value? Any idea why the value can't be changed on the vanilla split view? – beev Feb 17 '16 at 08:58
  • Had a chance to try this now. Works like a dream. I can't believe I spent so much time trying studying the split view delegate and didn't look properly at the docs for the split view itself. It doesn't say in the docs that subclassing is necessary, but it does seem to be the most efficient way to go about it since it makes sure the split view is configured before it is displayed. Thanks again! – beev Feb 17 '16 at 13:20
  • 11
    It's not necessary to subclass: if you have a pointer to the `UISplitViewController`, you can `aSplitViewController.preferredDisplayMode = .AllVisible`. If documentation was exhaustive, there wouldn't be StackOverflow, and I wouldn't have badges... – SwiftArchitect Feb 17 '16 at 15:31
  • 3
    Note that `.AllVisible` has been renamed to `.allVisible`. – JonJ Nov 03 '19 at 10:16
2

If anybody checks this topic lately the .allVisible was deprecated in IOS 14, use this: splitVC.preferredDisplayMode = .oneBesideSecondary

aSplitViewController.preferredDisplayMode = .oneBesideSecondary