I'm using a NavigationView to display "split view" style sidebar and secondary views similar to the Fruta sample app. My sidebar has a List of NavigationLink's, and my secondary view displays that linked content. However, I'm not able to set an initial "default" selection (i.e. blue background selected row style) for the List in my sidebar. When the app first launches, there's no selection state in the List for the secondary view that is displayed until the user taps a row of the List. I have a @State var called selection that's passed into my Sidebar, which references it as a @Binding. selection has a value, which is why it's unexpected that the resulting List doesn't show it as selected when first displayed.
EXPECTED RESULTS
When the app launches, I would expect the List selects the initial row matching the @Binding that's passed in.
ACTUAL RESULTS
When the app launches, The List has no initial selected row until the user taps a row.
I'd like for the user to launch into the app with a Sidebar List row already selected, similar to the way the Shortcuts app does when launched. How do I enable this kind of behavior?
Here's full demo code – iOS 14 beta 4, iPad in landscape:
EXPECTED RESULTS
When the app launches, I would expect the List selects the initial row matching the @Binding that's passed in.
ACTUAL RESULTS
When the app launches, The List has no initial selected row until the user taps a row.
I'd like for the user to launch into the app with a Sidebar List row already selected, similar to the way the Shortcuts app does when launched. How do I enable this kind of behavior?
Here's full demo code – iOS 14 beta 4, iPad in landscape:
Code Block swift import SwiftUI @main struct SidebarSelectionApp: App { var body: some Scene { WindowGroup { ContentView() } } } enum NavigationItem: Int, Identifiable { var id: Int { return self.rawValue } case view1 case view2 case view3 } struct ContentView: View { @State var selection: NavigationItem? = .view1 var body: some View { Sidebar(selection: $selection) } } struct Sidebar: View { @Binding var selection: NavigationItem? var body: some View { NavigationView { list EmptyView() } } var list: some View { List(selection: $selection) { NavigationLink( destination: View1(), tag: NavigationItem.view1, selection: $selection, label: { Text("View 1") }) NavigationLink( destination: View2(), tag: NavigationItem.view2, selection: $selection, label: { Text("View 2") }) NavigationLink( destination: View3(), tag: NavigationItem.view3, selection: $selection, label: { Text("View 3") }) } .listStyle(SidebarListStyle()) .navigationTitle("List") } } struct View1: View { var body: some View { Text("This is View 1").font(.title).foregroundColor(.green) } } struct View2: View { var body: some View { Text("This is View 2").font(.title).foregroundColor(.blue) } } struct View3: View { var body: some View { Text("This is View 3").font(.title).foregroundColor(.red) } }
No solution here. As far as I can tell, when SwiftUI instantiates or updates a
List
, it sets the bound selection variable to nil, and I have not been able to find any way to change this. For example, setting the selection variable in an.onAppear
modifier on the list doesn't work, because SwiftUI apparently clears the selection after theonAppear
action executes. I tried playing with the selection variable’sdidSet
property observer, but SwiftUI apparently clears the variable in a way that doesn’t triggerdidSet
. I’ve pretty much reached a dead end, too.