Along with the updated sidebar design introduced this year at WWDC, Apple gave us the ability to add multidimensional lists - that is - a list who's tree structure is recursive, in even simpler terms, multiple submenus. At the time of writing you'll need Xcode 12 beta 1 for this code to run.
Let's see an example using a menu with 3 levels, the structure looks like this.
Section
--- Menu Item
------ Menu Item
struct Menu: Identifiable {
var id = UUID()
let name: String
let icon: String
var children: [Menu]?
init(name: String, icon: String, children: [Menu]? = nil) {
self.name = name
self.icon = icon
self.children = children
}
}
let menuItems: [Menu] = [
Menu(name: "Section 1", icon: "", children: [
Menu(name: "Sub section 1", icon: "folder", children : [
Menu(name: "Detail 1", icon: "circle"),
Menu(name: "Detail 2", icon: "circle"),
Menu(name: "Detail 3", icon: "circle")
]),
Menu(name: "Sub section 2", icon: "pencil", children : [
Menu(name: "Detail 4", icon: "square"),
Menu(name: "Detail 5", icon: "square")
])
]),
Menu(name: "Section 2", icon: "", children: [
Menu(name: "Sub section 3", icon: "paperplane.fill", children : [
Menu(name: "Detail 6", icon: "circle"),
Menu(name: "Detail 7", icon: "circle"),
Menu(name: "Detail 8", icon: "circle")
]),
Menu(name: "Sub section 4", icon: "archivebox", children : [
Menu(name: "Detail 9", icon: "square"),
Menu(name: "Detail 10", icon: "square")
])
]),
Menu(name: "Section 3", icon: "doc", children: [
Menu(name: "Sub section 3", icon: "doc")
])
]
Here we have a simple Menu
model with an id, name, icon and children. We then create an array that represents our desired menu structure, as you can see we have Sections at the top level, with an array of children to represent our collapsable menu sections, then another array of children to represent our final menu items.
struct SideBar: View {
var body: some View {
List {
ForEach(menuItems) { menuItem in
Section(header: Text(menuItem.name)) {
OutlineGroup(menuItem.children ?? [Menu](),
children: \.children) { child in
Label(child.name, systemImage: child.icon)
}
}
}
}
.listStyle(SidebarListStyle())
}
}
Next we want to create a List
and iterate over this structure in a ForEach
, then use Section
to render our headers. We then move onto OutlineGroup
, this takes in our array of children
and the key path to the children
array in the menu model. OutlineGroup
is called recursively until there are no more children and renders a nice collapsable group.
To avoid nil coalescing here (??
) we could create a container model who's children is a non optional array of typeMenu

In this example we've used a List
, but OutlineGroup
can be used independently, another great use case is using it inside the new Form
View in SwiftUI. This can be as easy as changing List
to Form
in the above example.
Thanks for reading ✌️