40

I want to make my List inside a ScrollView so that I can scroll List rows and headers together.

But I found that List inside ScrollView isn't working. It shows nothing.

I should use both of them.

  • I should use ScrollView so that I can make my header(image or text) also scrolled when I scroll the rows.
  • I should use List to use .ondelete() method.

my sample code is below.

@State private var numbers = [1,2,3,4,5,6,7,8,9]

var body: some View {
    ScrollView {
        Text("header")
        List {
            ForEach(numbers, id: \.self) {
                Text("\($0)")
            }
            .onDelete { index in
                // delete item
            }
        }
    }
}

Anyone know why this happens and(or) how to fix?

pkamb
  • 33,281
  • 23
  • 160
  • 191
Jex Jang
  • 567
  • 1
  • 4
  • 9

4 Answers4

28

It is possible but not when the List is using the full screen.

In the code example I used GeometryReader to make the list as big as possible. But you can also remove the GeometryReader and just insert a fixed dimension into .frame()

struct ContentView: View {
    
    @State private var numbers = [1,2,3,4,5,6,7,8,9]
    
    var body: some View {
        GeometryReader { g in
            ScrollView {
                Text("header")
                List {
                    ForEach(self.numbers, id: \.self) {
                        Text("\($0)")
                    }
                    .onDelete { index in
                        // delete item
                    }
                }.frame(width: g.size.width - 5, height: g.size.height - 50, alignment: .center)
            }
        }
    }
}

enter image description here

pkamb
  • 33,281
  • 23
  • 160
  • 191
Volker88
  • 574
  • 1
  • 5
  • 15
  • Thank you! Never guessed this solution. Do you know why full framed list is not on the screen? – Jex Jang Mar 16 '20 at 12:53
  • 1
    I have no idea. I was just surprised that it's not working when i saw the code here because I use List inside ScrollView since early betas in my App. Then i noticed that i don't use it full screen. – Volker88 Mar 16 '20 at 17:30
  • 1
    A `List` is sized based on its container, so inside a `ScrollView` it collapses entirely, unless you give it an explicit size. The answer to this question explains it better: https://stackoverflow.com/questions/61437905/swiftui-list-is-not-showing-any-items – John Nimis Oct 06 '21 at 15:44
20

There is no need for two scrolling objects. You can also use section for this:

@State private var numbers = [1,2,3,4,5,6,7,8,9]

var body: some View {
    List {
        Section.init {
            Text("Header")
        }
        ForEach(numbers, id: \.self) {
            Text("\($0)")
        }
        .onDelete { index in
            // delete item
        }
    }
}
pkamb
  • 33,281
  • 23
  • 160
  • 191
Anil Kumar
  • 1,830
  • 15
  • 24
3

Just put header inside the List, like

demo

var body: some View {
    List {
        Text("Header").font(.title)
        ForEach(numbers, id: \.self) {
            Text("\($0)")
        }
        .onDelete { index in
            // delete item
        }
    }
}
Asperi
  • 228,894
  • 20
  • 464
  • 690
0

If you want a header, use a section.

var body: some View {
    List {
        Section {
            ForEach(numbers, id: \.self) {
                Text("\($0)")
            }
            .onDelete { index in
                // delete item
            }
        } header: {
            Text("Header").font(.title)
        }            
    }
}
Xaxxus
  • 1,083
  • 12
  • 19