'SwiftUI - nested list

I'm trying to create a nested hierarchical list, so that for each task I can have subtasks like in iOS reminders app:

enter image description here

First attempt was to embed another list inside a list cell.

import SwiftUI

struct SwiftUIView: View {
    var body: some View {

        List {
            List {
              Text("Hello, World!")

            }

        }
    }
}

struct SwiftUIView_Previews: PreviewProvider {
    static var previews: some View {
        SwiftUIView()
    }

But, didn't work out...

Anyone can help?

cheers



Solution 1:[1]

Why do you think it should be List in List... Such visual representation can be generated using only one list and it will have native look & feel.

Here is just a demo (w/o UI tuning and logic of showing/hiding sections, that is out of topic), but the idea should be clear

nested list

struct ItemRow: View {
    let category: Bool
    let text: String
    
    init(_ text: String, isCategory: Bool = false) {
        self.category = isCategory
        self.text = text
    }
    
    var body: some View {
        HStack {
            Circle().stroke() // this can be custom control
                .frame(width: 20, height: 20)
                .onTapGesture {
                    // handle tap here
                }
            if category {
                Text(self.text).bold()
            } else {
                Text(self.text)
            }
        }
    }
}

struct TestNestedLists: View {
    var body: some View {
        List { // next pattern easily wrapped with ForEach
            ItemRow("Category", isCategory: true) // this can be section's header
            Section {
                ItemRow("Item 1")
                ItemRow("Item 2")
                ItemRow("Item 3")
            }.padding(.leading, 20)
        }
    }
}

backup

Solution 2:[2]

It's not hard, but you have to manually add some frame.

        struct SwiftUIViewList: View {
            var body: some View {
                    List {
                      Text("Hello, World!")
                      Text("Hello, World!")
                }
            }
        }

        struct SwiftUIView: View {
            var body: some View {

                List {

                   Text("item1")
                    SwiftUIViewList().frame(height: 100)
                   Text("item3")
                }
            }
        }

Solution 3:[3]

Place one list inside another, like this small example:

struct ContentView: View {
    var body: some View {
        List {
            Text("External List")
            List {
                Text("Internal List")
            }
        }
    }
}

It results in this: Result Error

I was testing and found that the error occurs when the style of the inner list is any grouped style (.grouped, .insetGrouped or the new .sidebar).

In contrast, if the internal list has any non-grouped style (.inset or .plain) it works correctly.

struct ContentView: View {
    var body: some View {
        List {
            Text("External List")
            List {
                Text("Internal List")
            }
            .listStyle(.plain)
        }
    }
}

It results in this: Result OK

Beyond this, as mentioned in many places, you should not use nested lists. You should try to resolve with VStack or ForEach.

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
Solution 2 E.Coms
Solution 3 GustavoLizio