Advice on achieving desired, adaptive UISplitViewController behaviors in iOS 8+

232 views Asked by At

I'm trying to achieve a set of adaptive behaviors with a Master/Detail UISplitViewController in iOS 8+ that seem to me intuitive, but are not (so far as I have been able to discover) "typical" of Apple's examples or implemented in any of the various iOS 8+ UISplitViewController tutorials I've seen. So I turn here for advice, figuring that I can't be the first to want these behaviors, which are:

1) On all iPhones (plus or not) in portrait orientation, selecting a cell in the Master table view "pushes" the Detail view on screen and animates the Master table view off screen — i.e., the usual navigation controller behavior.

2) On all iPhones (plus or not) in landscape orientation, and on iPads in all orientations, the Master view stays visible after cell selection, until/unless the user a) taps inside the Detail view or b) taps on a "full-screen" button in the Detail view's top bar, at which point the Master view animates out of view.

3) On all iPhones (plus or not) in landscape orientation, and on iPads in all orientations, the Detail view dynamically resizes such that a) when the Master view is showing, no part of the Detail view is overlaid/obscured by the Master view, and b) when the Master view is not showing, the Detail view occupies the whole width of the screen.

4) On all devices and in all orientations, when the Master view is not showing, tapping a button in the Detail view's top bar, causes the Master view to animate onto the screen — i.e., as a "pop" on all iPhones in portrait orientation, and as a Detail-view-squeezing "pane" on all iPhones (plus or not) in landscape orientation and on iPads in all orientations.

In other words, on all devices in all orientations — except on iPhones in portrait orientation, in which case the usual navigation controller behavior should obtain — the Master view should be a Detail-view-squeezing (not overlaying/obscuring) "pane" that remains visible until/unless the user taps inside the Detail view or on a "go-to-fullscreen" button in the Detail view's top bar; at which point the Master view should animate off screen and the Detail view should occupy the full width of the screen.

Any advice/sample code/links to same will be greatly appreciated! (I'm working in Swift these days, but can adapt Objective-C code to Swift readily enough.)

Thanks,

Carl

UPDATE 1

Requirements 2 and 3 above turn out to be easy to achieve on the iPad simply by setting the UISplitViewController's preferredDisplayMode property to .AllVisible (Obj-C = UISplitViewControllerDisplayModeAllVisible). As a side-bonus, this mode gives me the desired "go-to-fullscreen" button in the Detail view's top bar.

However, I still can't get the desired behavior — i.e., keeping both primary (Master) and secondary (Detail) view controllers always visible in landscape mode — on any iPhone but the 6+. I'd hoped that overriding viewWillTransitionToSize:withTransitionCoordinatorin my custom UISplitViewController to set its secondary view controller's size class to UITraitCollection(horizontalSizeClass: .Regular) would do the trick, but no such luck: iOS seems to ignore this overriding size class when doing landscape layout on iPhone.

One example I've seen (in Ray Wenderlich's "iOS 8 by Tutorials") suggests that the way to achieve what I want on all iPhones (well, possibly excluding the iPhone 4s, since it's screen is so "short") is to embed the UISplitViewController in a container view of a parent view controller, and override that parent view controller's viewWillTransitionToSize:withTransitionCoordinator method to set the child UISplitViewController's size-class. I'm willing to do this, if that's the correct or only way, but it seems like a kludge that I'd like to avoid if possible.

UPDATE 2

I've tried Ray Wenderlich's technique for extending iPhone-6+-like UISplitViewController landscape behavior to other iPhones, and can confirm that it works. I'd even say if feels a bit less kludgy than I'd thought, though it's still not what I would consider a "pure" solution (in the sense of it not being one I'd arrive at from a strict UI-design approach).

If someone knows of a more direct way to achieve this behavior, I'd still like to know it. So I'll leave this here for anyone else wanting this behavior, and "unanswered" for the purpose of soliciting a better solution.

0

There are 0 answers