'SwiftUI: How do you implement List + ForEach loop for child elements (shown in a disclosure group)?

Currently, my app uses only a list view to display folders (as seen below). All of the tutorials online suggest that for dynamic content (In my case, an array of folders that will be updated once a user adds a new one), I should use a ForEach loop inside of a List. The problem for my app, however, is that I need the ForEach loop, which consists of Navigation Views (as seen below), to work infinitely -- I need a ForEach loop that allows for infinitely many disclosure groups/subfolders. I have found no tutorials online that detail/show how to create a List, with a ForEach loop, with children items in a disclosure group. Therefore, I have stuck with strictly just the List view, since it includes a "children" parameter (as shown in my code). The reason why I need a dynamic ForEach loop is that I need to add an onDelete modifier.

enter image description here

Code:


List(searchResults, id: \.self, children: \.subFolders, selection: $selection) { folder in
                Label(folder.title, systemImage: "folder")
                .swipeActions {
                    Button(role: .destructive) { folder.delete() } label: { Label("Delete", systemImage: "trash") }
                    Button {} label: { Label("Move", systemImage: "rectangle.portrait.and.arrow.right") }
                }
                
                NavigationLink(destination: DirectoryView(directory: folder)) { EmptyView() }
                .frame(width: 0)
                .opacity(0)
            }
            .listStyle(.automatic)
            .searchable(text: $searchText)
            NavigationLink(isActive: $newDirAlert.showNewItem) { DirectoryView(directory: Folder.parentFolders.last ?? Folder()) } label: { EmptyView() }



Solution 1:[1]

use DisclosureGroup

List {
  ForEach(searchResults, id: \.self, selection: $selection) { folder in
      DisclosureGroup {
          ForEach(folder.subFolders) { folder in
              Label(folder.title, systemImage: "folder")
                  .swipeActions {
                      Button(role: .destructive) { folder.delete() } label: { Label("Delete", systemImage: "trash") }
                      Button {} label: { Label("Move", systemImage: "rectangle.portrait.and.arrow.right") }
                  }
              
              NavigationLink(destination: DirectoryView(directory: folder)) { EmptyView() }
                  .frame(width: 0)
                  .opacity(0)
          }
      } label: {
          Label(folder.title, systemImage: "folder")
              .swipeActions {
                  Button(role: .destructive) { folder.delete() } label: { Label("Delete", systemImage: "trash") }
                  Button {} label: { Label("Move", systemImage: "rectangle.portrait.and.arrow.right") }
              }

          NavigationLink(destination: DirectoryView(directory: folder)) { EmptyView() }
              .frame(width: 0)
              .opacity(0)
      }
  }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1