SwiftUI macOS app changes sidebar height on focus?

Viewed 339

I'm having an issue with the Sidebar in a SwiftUI macOS app. When the app is first launched, without focus, there is an extra top padding in the sidebar, which gets collapsed to the correct size, when the window gets focus. This seems like a bug to me. Any way to fix this, or am I doing something wrong?

Before (No Focus)

enter image description here

After (Focus)

enter image description here

As you can see, the space between "Inbox" and the three traffic light dots are different in these two cases.

enter image description here

Code

Here is the code for the sidebar:

NavigationView {
    List {
      Text("Inbox")
      
      Section(header: Text("All projects")) {
        ForEachStore(
          self.store.scope(state: { $0.projects }, action: AppAction.project(id:action:)), content: { projectStore in
            WithViewStore(projectStore) { projectViewStore in
              NavigationLink(
                destination: ProjectView(store: projectStore),
                label: {
                  Text(projectViewStore.title)
                })
            }
          }
        )
        Spacer()
      }
    }.frame(minWidth: 160)
    .listStyle(SidebarListStyle())
    HStack {     
      HStack {
        Button("−") { viewStore.send(.decrementButtonTapped) }
        Text("\(viewStore.count)")
        Button("+") { viewStore.send(.incrementButtonTapped) }
        
      }
    } 
  }
2 Answers

This looks like effect of NavigationView titlebar, try to make it empty explicitly, like

}.frame(minWidth: 160, maxHeight: .infinity)     // also try this !!
.listStyle(SidebarListStyle())
.navigationTitle("")             // << here !!

Update another idea - give explicit list row insets

NavigationView {
    List {
      Text("Inbox")
         .listRowInsets(EdgeInsets(top: 0, leading: 0, bottom: 0, trailing: 0))

I figured it out with some help. Here is a working solution.

NavigationView {
        List {
          Section(header: Text("All projects")) {
            ForEachStore(
              self.store.scope(
                state: { $0.projects },
                action: AppAction.project(id:action:)),
              content: { projectStore in
                NavigationLink(
                  destination: ProjectView(store: projectStore).edgesIgnoringSafeArea(.all),
                  label: {
                    EditableListItemView(store: projectStore)  
                  })
              }
            )
          }
        }
        .overlay(SidebarBottomView(store: store), alignment: .bottom)
        .frame(minWidth: 160, maxHeight: .infinity)
        .listStyle(SidebarListStyle())
        Text("Nothing here")
        
  }

The key part is the .edgesIgnoringSafeArea(.all) on the destination view. It also has to be specified at that "level" in the view hierarchy.

Related