Mac Catalyst and UISplitViewController

Today I learned that a UISplitViewController behaves differently in a Mac Catalyst app when it is the root of a window versus if it is wrapped in a window. If you want Mac-style toolbar behaviors, make it the root of a window.

Library Notes uses a UISplitViewController for its main screen. When I first wrote this app, I was deep into the “composition instead of inheritance” philosophy, and I used view controller containment to avoid subclassing UISplitViewController. I created a class called NotebookViewController to manage the UISplitViewController. NotebookViewController creates the split view controller & adds it as a child view controller that completely fills its view.

Running on iOS, it looks like a normal UISplitViewController fills the whole screen.

Now that I’m working on porting Library Notes to the Mac using Catalyst, though, I noticed something: Even when I tell Xcode that I want to optimize for the Mac interface, I still get iOS-style bar button items displayed in the navigation bar instead of Mac-style buttons displayed in the toolbar. My UI looked like this:

UISplitViewController with iOS-style buttons

I suspected that Mac Catalyst did something different if the window’s rootViewController is a UISplitViewController, so I rewrote NotebookViewController to be a UISplitViewController rather than contain a UISplitViewController. Sure enough, after that simple change, my UI looked like this:

UISplitViewController with a Mac-style toolbar

In retrospect, this makes perfect sense. Mac Catalyst will adapt iOS components to a Mac interface based upon what those components are. Something to keep in mind if, like me, you are an iOS developer venturing into Mac-land for the first time.