Exception when going from compact to regular with the new UISplitViewController on iOS 14

If the app starts on regular mode, changes to compact, and then changes back to regular, everything works fine. The problem happens when the app starts on compact mode. When trying to switch to regular, the following exception happens and the app crashes:

Code Block
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Unexpected view controller change in Secondary column for expanding <UISplitViewController: 0x10550a630>'


I have a sample project on Github that we can use to simulate this. Just follow the steps to reproduce:
  1. Launch the app

  2. Open another app on the side in a way that the first app changes to compact mode

  3. Relaunch the app

  4. Slide the second app off the screen so that the first changes to regular mode

Is this a bug on the API, or I'm using it incorrectly? Thanks.

Replies

What I found is that when you manipulate the view controllers during the transition from compact to regular, you need to put a short delay on that manipulation so that the runloop has a chance to complete first.
Hello, I used your sample project as my starting point for iOS 14's Sidebar, so first : thanks. :)

I have the same problem: I launch the app in compact mode (XS Max or your steps on iPad simulator), then I rotate the phone to go primary/secondary and it crashes.

HOWEVER, I just tried launching the app from the Home screen, without Xcode, and it works as it should be. I think it's more of a debugger/Xcode issue.
I am running into this issue as well, I hope that Apple has the time (even with the event tonight) to research this issue or communicate what we're doing wrong.
I fixed the crash by setting initially secondary, controller at the same time as primary and compact controllers.
So I had a custom class
Code Block
class SplitController: UISplitViewController {
override init(style: UISplitViewController.Style) {
        super.init(style: style)
        setupAppearance()
    }
// ....
private func setupAppearance() {
        delegate = self
        setViewController(sidebar, for: .primary)
        setViewController(TabBarController(rootTabs: rootTabs), for: .compact)
    }
}


and a sidebar had this implementation:

Code Block
class SideBarController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// ...
        splitViewController?.setViewController(mycontroller, for: .secondary)
    }
}


And whenever I was launching app with compact controller, it would crash when expanding to regular mode.
I solved it by modifying setupAppearance method to:
Code Block
private func setupAppearance() {
        delegate = self
        setViewController(sidebar, for: .primary)
        setViewController(homeController, for: .secondary)
// or even, if you really don't care for some reason
// setViewController(UIViewController(), for: .secondary)
        setViewController(TabBarController(rootTabs: rootTabs), for: .compact)
    }