What pattern to use for an iPhone Tabview app

I have an iPhone tab view application that has not been designed for iPad, and I am aiming to add a left-hand bar that summarises some content and keeps visible what is normally a sheet. What pattern would work best for this?

At present, I pass the view to another view with a navigation stack containing an arrangement view with the previous view and then the sidebar as a secondary view within it—would that be the appropriate approach?

Answered by DTS Engineer in 906614022

Hi @craigmpeters2,

A NavigationSplitView or UISplitViewController manages the presentation of multiple adjacent panes of content, automatically handling layout collapse into a single stack on compact displays like standard iPhones while expanding appropriately on larger or unfolding screens.

Embedding your lists and primary navigation views directly into a split view provides the correct semantic structure for sidebar patterns, superseding custom arrangement views for hierarchical navigation. To learn more, see Building lists and navigation.

An ArrangementView in SwiftUI and UIArrangementViewController in UIKit are layout containers for a primary view and a secondary view designed to adapt to different device poses and reserved regions, such as folding areas.

Avoid placing an arrangement view inside a navigation split view, list, or scroll view where part of your view might become inaccessible. Place navigation containers around arrangement views rather than within them.

Rather than maintaining a custom ArrangementView hierarchy that mimics split behaviors, refactor your application to use standard system containers like NavigationSplitView to get proper responsive behavior and platform-consistent visuals automatically.

For more guidance, see Preparing your app for iPhone Duo.

Cheers,

Paris X Pinkney |  WWDR | DTS Engineer

Hi @craigmpeters2,

A NavigationSplitView or UISplitViewController manages the presentation of multiple adjacent panes of content, automatically handling layout collapse into a single stack on compact displays like standard iPhones while expanding appropriately on larger or unfolding screens.

Embedding your lists and primary navigation views directly into a split view provides the correct semantic structure for sidebar patterns, superseding custom arrangement views for hierarchical navigation. To learn more, see Building lists and navigation.

An ArrangementView in SwiftUI and UIArrangementViewController in UIKit are layout containers for a primary view and a secondary view designed to adapt to different device poses and reserved regions, such as folding areas.

Avoid placing an arrangement view inside a navigation split view, list, or scroll view where part of your view might become inaccessible. Place navigation containers around arrangement views rather than within them.

Rather than maintaining a custom ArrangementView hierarchy that mimics split behaviors, refactor your application to use standard system containers like NavigationSplitView to get proper responsive behavior and platform-consistent visuals automatically.

For more guidance, see Preparing your app for iPhone Duo.

Cheers,

Paris X Pinkney |  WWDR | DTS Engineer

So if I am understanding this correctly it would go:

NavigationSplitView {
    View { ...Sidebar } 
    TabView {
         NavigationStack {
            List { .... }
            .toolbar { Primary / Secondary Action }
         }
    }
}
.onChange(of: sizeClass) {
   manage detail / automatic
}

Hi @craigmpeters2,

Your structure is close, but I'd change two things. Keep the TabView as the root, and put a persistent summary column beside it only in regular width. Don't wrap the TabView in the NavigationSplitView's detail column unless you want the split view to own navigation.

  • Both TabView and NavigationSplitView, independently, are intended to be used as the root view of a scene.
  • NavigationSplitView is designed for selection-driven columns: choosing something in a leading column changes what the later columns show. A summary panel that mirrors a sheet isn't selection-driven.
  • On compact widths, such as when iPhone Duo is closed, or opened flat in Split View, NavigationSplitView collapses into a single stack and ignores column visibility.
  • The .onChange(of: sizeClass) usage is a sign this architectural structure is fighting against the framework.
struct RootView: View {
    @Environment(\.horizontalSizeClass) private var sizeClass
    @State private var model = Model()

    var body: some View {
        HStack(spacing: 0) {
            if sizeClass == .regular {
                SummarySidebar(model: model)   // the content formerly in the sheet
                    .frame(width: 320)
                Divider()
            }
            TabView { ... }
        }
        .sheet(isPresented: $showSummary) {   // compact only
            SummarySidebar(model: model)
        }
    }
}

Please let me know if you have any questions.

Cheers,

Paris X Pinkney |  WWDR | DTS Engineer