I have a set up where I have two DisclosureGroups and list of items beneath them:
struct HomeView: View
{
@State private var selectedItem: String?
var body: some View
{
VStack
{
List
{
DisclosureGroupWithButton(title: "Group 1", items: ["Item 1", "Item 2", "Item 3"])
DisclosureGroupWithButton(title: "Group 2", items: ["Item A", "Item B", "Item C"])
}
.listStyle(SidebarListStyle())
List(selection: self.$selectedItem)
{
ForEach(["Option 1", "Option 2", "Option 3"], id: \.self)
{
item in Text(item) .tag(item)
}
}
.frame(maxHeight: .infinity)
}
}
}
struct DisclosureGroupWithButton: View
{
let title: String
let items: [String]
@State private var isExpanded: Bool = false
var body: some View
{
DisclosureGroup(isExpanded: self.$isExpanded)
{
ForEach(items, id: \.self)
{
item in Text(item)
}
Button("Add Item")
{
print("\(title) button tapped")
}
.buttonStyle(.bordered)
.padding(.top, 5)
}
label:
{
Text(self.title)
}
}
}
I want to make it so the List at the bottom appears almost directly beneath the two DisclosureGroups with a little space separating them (and no white space), but I am struggling to do so. The obvious solution is to use a spacer after the List, but that does nothing for some reason. I've messed around with the frames of all the elements and nothing changes. I also noticed that the same behavior occurs even when I strip this down to it's very bare elements of simply being two lists:
struct HomeView: View
{
@State private var selectedItem: String?
var body: some View
{
List
{
ForEach(["Option 1", "Option 2", "Option 3"], id: \.self)
{
item in Text(item) .tag(item)
}
}
List(selection: self.$selectedItem)
{
ForEach(["Option 1", "Option 2", "Option 3"], id: \.self)
{
item in Text(item) .tag(item)
}
}
}
}
Does anyone know how to accomplish this?
It seems like you just want a single List
with 2 sections.
List(selection: self.$selectedItem) {
Section {
DisclosureGroupWithButton(title: "Group 1", items: ["Item 1", "Item 2", "Item 3"])
DisclosureGroupWithButton(title: "Group 2", items: ["Item A", "Item B", "Item C"])
}
.selectionDisabled()
Section {
ForEach(["Option 1", "Option 2", "Option 3"], id: \.self) {
item in Text(item) .tag(item)
}
}
}
// .listSectionSpacing(...) // if you want to adjust the spacing
.listStyle(.sidebar)
I put .selectionDisabled()
on the first section to prevent selecting things from the first section. If the first section is also selectable, you can use an enum with associated values as the type of selection, and change the tag
s accordingly. e.g.
enum ListSelection {
case section1(SomeOtherType)
case section2(String)
}