Search code examples
swiftmacosswiftuinavigationlink

SwiftUI sidebar list does not register first click


Using SwiftUI, I have a sidebar navigation in a Mac app to change views. Clicking an item in the sidebar changes the view on the right. However, when the app is launched, the sidebar List does not register the first click. It takes two clicks to select an item. Afterwards, the sidebar behaves as it should and only requires one click to change the view.

How can I fix this initial launch issue with the List?

sidebar navigation

import SwiftUI

struct DetailView: View {

    var selection: String

    var body: some View {
        containedView()
    }

    private func containedView() -> AnyView {
        switch selection {
        case "🍎 Apple":
            return AnyView(AppleView())
        case "🍌 Banana":
            return AnyView(BananaView())
        case "🥥 Coconut":
            return AnyView(CoconutView())
        default:
            return AnyView(Text("Some view here").frame(maxWidth: .infinity, maxHeight: .infinity))
        }
    }
}

struct SidebarView: View {

    let items = ["🍎 Apple", "🍌 Banana", "🥥 Coconut", "🍒 Cherry", "🥜 Peanut", "🍑 Peach", "🍅 Tomato", "🍞 Bread", "🍕 Pizza", "🥦 Broccoli", "🥝 Kiwi", "🧀 Cheese", "🍉 Watermelon"]

    var body: some View {
        List(items, id: \.self) { item in
            NavigationLink(destination: DetailView(selection: item)) {
                Text("\(item)")
            }
        }
        .listStyle(SidebarListStyle())
    }
}

struct ContentView: View {
    var body: some View {
        NavigationView {
            SidebarView()
            DetailView(selection: "🍎 Apple")
        }
        .frame(height: 300)
    }
}

Solution

  • It is needed to add selection for List, like below

    @State var current = Set<String>()
    var body: some View {
        List(items, id: \.self, selection: $current) { item in
            NavigationLink(destination: DetailView(selection: item)) {
                Text(item)
            }
        }
        .listStyle(SidebarListStyle())
    }