&TLDR; I see no documentation stating that during the life of UISplitViewController, that I cannot call setViewController(xxxxx, column) more than once on the same column. Yet in my experience calling it a second time does not work, unless I set the value to nil before calling it again to set it to the new value...
I'm using a UISplitViewController in newer column-style layout and when bootstrapping the app, I create the UISplitViewController and use setViewController(primaryViewController, .primary) and setViewController(detailViewController, .secondary).
In order to use the primaryViewController for the compact scenario, I return the .primary column in the UISplitViewControllerDelegate method:
splitViewController(_ svc: UISplitViewController, topColumnForCollapsingToProposedTopColumn proposedTopColumn: UISplitViewController.Column) -> UISplitViewController.Column
Tapping a cell in the primaryViewController, results in a call to
splitViewController.show(.secondary)
This works for both split view (primary + secondary) as well as in compact mode.
Tapping a cell in the secondary viewController results in pushing a new sub-detail onto the navigation sack. Again so far so good.
If I switch back to split mode (primary+secondary) it still looks good with secondary showing the sub-detail.
If I then collapse into compact view, the primary is once again shown. If I tap a different cell in the primary, the same call to:
splitViewController.show(.secondary)
results in the sub-detail viewController being shown. Instead, I want the secondary to show the detail for the new selected cell...not the sub-detail of the prior cell.
To fix this, I popped the navigation stack for the secondary to rootViewController
if secondaryNavigationController.topViewController as? DetailViewController == nil {
secondaryNavigationController.popToRootViewController(animated: false)
next, I attempted to replace splitViewController's secondary viewController by assigning the secondaryNavigationController which now has the DetailViewController as the top (and only) viewController.
splitViewController.setViewController(secondaryNavigationController, for: .secondary)
after this assignment, calling
splitViewController.viewController(for: .secondary)
returns the old sub-detail viewController, not the expected DetailViewController!
IMO this is a bug.
I found the following solution. First set it to nil, then set it to the desired value.
splitViewController.setViewController(nil, for: .secondary)
splitViewController.setViewController(secondaryNavigationController, for: .secondary)