max
max

Reputation: 447

Sidebar tracking toolbar items in SwiftUI

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!

Upvotes: 4

Views: 1644

Answers (1)

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")
        })
    }
}

Upvotes: 2

Related Questions