MacOS: Spacing between NavigationLink-s in a sidebar with NavigationView.

How can I put one list item at the top and another one at the bottom, retaining the NavigationView functionality?

Here is a simple app:

struct ContentView: View {
    var body: some View {
        NavigationView {
            Sidebar()
        }
    }
}

struct Sidebar: View {
    @State private var isActive = true
    
    var body: some View {
        List {
            NavigationLink(isActive: $isActive) {
                HomeView()
            } label: {
                Text("Home")
            }
            
            NavigationLink {
                SettingsView()
            } label: {
                Text("Settings")
            }
        }
    }
}

struct HomeView: View {
    var body: some View {
        VStack {}
        .navigationTitle("Home")
    }
}

struct SettingsView: View {
    var body: some View {
        VStack {}
        .navigationTitle("Settings")
    }
}

Which looks like this:

My initial though was to put a Spacer() between each NavigationLink, but it results in an unexpected view:

What i can do:

  1. Place an empty VStack between each NavigationLink with a hard-coded height like this:
VStack {}.frame(height: 275)

Which looks like this:

But it wouldn't work if a user would want to increase the height of a window. I could disable window resizing which is kind of fine, but not the most optimal.

  1. Another obvious option was to replace the List with a VStack, but with this approach the styling of the NavigationLink gets broken and it does not get highlighted when I click on it.

It looks like this:

P.S. I know that NavigationView is deprecated, but i want to support macOS 12.0.

Answered by Kopyl in 827334022

Just posted the same to Claude and it gave me this solution which works:

struct Sidebar: View {
    @State private var isActive = true
    
    var body: some View {
        VStack {
            List {
                NavigationLink(isActive: $isActive) {
                    HomeView()
                } label: {
                    Text("Home")
                }
            }
            
            List {
                NavigationLink {
                    SettingsView()
                } label: {
                    Text("Settings")
                }
            }
            .frame(height: 50)
        }
    }
}
Accepted Answer

Just posted the same to Claude and it gave me this solution which works:

struct Sidebar: View {
    @State private var isActive = true
    
    var body: some View {
        VStack {
            List {
                NavigationLink(isActive: $isActive) {
                    HomeView()
                } label: {
                    Text("Home")
                }
            }
            
            List {
                NavigationLink {
                    SettingsView()
                } label: {
                    Text("Settings")
                }
            }
            .frame(height: 50)
        }
    }
}
MacOS: Spacing between NavigationLink-s in a sidebar with NavigationView.
 
 
Q