Sidebar tracking toolbar items in SwiftUI

1k Views Asked by At

Is there an official way to achieve an equivalent of an NSTrackingSeparatorToolbarItem consistently in SwiftUI yet?

I'm making an app that has 2 possible toolbar states, both have a "toggle sidebar" button I'd like to be in the actual sidebar, kinda like Xcode. I'm using a NavigaionView and I'm adding the sidebar button as follows:

NavigationView {
  List(selection: $selection) {
    ForEach(app.menuItems) { menuItem in
      Section(header: MenuSectionHeader(menuItem.name)) {
        OutlineGroup(menuItem.children ?? [SidebarItem](), children: \.children) { child in
          Label(child.name, systemImage: child.icon)
        }
      }
    }
  }
  .toolbar {
    ToolbarItem(placement: .automatic) {
      Button(action: toggleSidebar) {
        Icon(icon: "sidebar.left", .textDim)
      }
    }
  }

  DetailsView()
    .toolbar {
      // ...rest of the toolbar...
    }
}

And it works in one of the 2 states:

expanded sidebar

collapsed sidebar

But in the other state, the .automatic placement pushed it next to the center area:

wrong placement

There's nothing in the official ToolbarItemPlacement docs that suggests it's possible to force a ToolbarItem to be in the sidebar, but given that automatic placement pushes it there sometimes, maybe there's something I'm missing.

Any ideas are welcome!

1

There are 1 best solutions below

0
Alkenso 'Volodymyr Vashurkin' On

If you want to put toolbar items inside the sidebar, attach toolbar modifier to List with SidebarStyle

List {
    Text("foo")
    Text("bar")
}
.listStyle(.sidebar)
.toolbar {
    ToolbarItemGroup {
        Button(action: {}, label: {
            Image(systemName: "sidebar.left")
        })
        Spacer()
        Button(action: {}, label: {
            Image(systemName: "play.fill")
        })
        Button(action: {}, label: {
            Image(systemName: "stop.fill")
        })
    }
}