Using Sidebar in SwiftUI Without a NavigationView
Get to know SwiftUI’s new sidebar

SwiftUI is really easy and fast for prototyping UI. This opinion has been expressed by many developers in different wordings.
But how does SwiftUI fare against the complex requirements of a real-world project? At present, it has been in production for only just over a year, and we can’t find many SwiftUI apps in the App Store.
But if there is any good time to build and ship SwiftUI apps, it is right now.
Disclaimer: Your app’s minimum target needs to be iOS 13.
Even though most of the SwiftUI features which make it production-ready have shipped only with iOS 14, you can build a decent app for iOS 13 which becomes exceptional when the user updates.
Take the common requirement of a collection view in many apps. You can use the new lazy grids for iOS 14 and drop down to a combination of VStack
and HStack
as Paul explains in this article for iOS 13. Also, if your requirement can just be fulfilled using a list, then go for it in iOS 13.
But if your requirements are complex or you want to tweak the default behavior a little bit, you might find it difficult. Today we’ll tackle one such scenario where I want some tweaks to the default behavior. Over the coming weeks, we’ll see many more.
SidebarListStyle
was introduced this year, and makes it so easy to get the default sidebar behavior in your app.
Just with those few lines, you get the default behavior of the sidebar in a nice master detail layout.

You get a lot of things out of the box: a sidebar with spaced out list items, no separators, a nice indication for the selection, and a button to toggle the visibility of the sidebar. If you use the new Label
for the list item, the images will be in the accentColor
. So cool, with just a few lines of code! Now my requirement is to have the sidebar and the detail view, but I don't want them to be inside a NavigationView
. Sounds simple, right? Let’s try.
And the output is…

Not what I expected to see from the above code. But SwiftUI views react to the environment; you can say that SwiftUI views are dependent on the environment. We got the spaced-out list items without a separator but no selection and hence no highlighting when tapped, and we need to frame the views in the required size.
I have no clue why removing the NavigationLink
stops the List
selection from working. You can get it to work by adding an onTapGesture
to the Text
. The selection
parameter in the list in no longer required. You can fix the sidebar width by using the frame
modifier.
Let’s try our luck this time.

Again, this is not what I expected, but SwiftUI did its job perfectly. We can fix this easily by adding a Spacer()
before and after detailView
.
The functionality is working properly, so you can tap any item to select it. But there is no visual indication of which item is currently selected. To highlight the selection, add a background
with accentColor
.
Here’s the final output.

And here’s the code to get that output.
We’ve used an HStack
and a contentShape
modifier so that tapping anywhere on the list item enables selection.
This is not the perfect solution, but this works. It took me some mental preparation to share working solutions publicly rather than waiting for the perfect solution all the time.
Happy coding!