Reading time: 1 min

This recipe shows how to implement sticky headers & footers when using a LazyVStack or LazyHStack instead of a List.

The end result looks like this:

preview

This solution relies on PinnedScrollableViews, which are options that can be passed in the pinnedViews argument of LazyVStack and LazyHStack initializers. While populating a scrollable vertical or a horizontal stack with a ForEach, use the Section view and specify its header and/or footer. Here's the full code:

ScrollView {
  LazyVStack(pinnedViews: [.sectionHeaders, .sectionFooters]) { // HERE
    ForEach(1..<10) { i in
      Section {
        Text("\(i)")
          .font(.system(size: 60))
      } header: {
        Text("Header: \(i)")
          .font(.system(size: 24))
          .padding()
          .frame(maxWidth: .infinity)
          .background(Color.blue)
      } footer: {
        Text("Footer: \(i)")
          .font(.system(size: 24))
          .padding()
          .frame(maxWidth: .infinity)
          .background(Color.red)
      }
    }
  }
}

Of course, the same things works with horizontall scrolling as well:

ScrollView([.horizontal]) {
  LazyHStack(pinnedViews: [.sectionHeaders, .sectionFooters]) {
    ForEach(1..<10) { i in
      Section {
        Text("\(i)")
          .font(.system(size: 60))
      } header: {
        Text("Header: \(i)")
          .font(.system(size: 24))
          .padding()
          .background(Color.blue)
      } footer: {
        Text("Footer: \(i)")
          .font(.system(size: 24))
          .padding()
          .background(Color.red)
      }
    }
  }
}

Next Post Previous Post