SwiftUI: Pinned header view inside horizontal scroll view for lazy grid

Viewed 1110

I would like to add a pinned header view to a lazy grid. The lazy grid should be horizontally scrollable.

The problem is that above and below there is also content which should not scroll horizontally. Otherwise the problem could be solved easily by setting the outer ScrollView scrolling behavior to ([.horizontal, .vertical]) and remove the inner.

In the example code everything works correctly, but the header view is not pinned at the top when scrolling vertically. It scrolls away like any other content above the grid. Maybe this is an issue with SwiftUI itself.

struct ContentView: View {
    var body: some View {
        ScrollView(.vertical) {
            Text("Other content")
                .frame(maxWidth: .infinity, minHeight: 100)
                .background(Color.yellow)

            ScrollView(.horizontal) {
                LazyVGrid(
                    columns: Array(repeating: GridItem(.fixed(200), spacing: 0, alignment: .center), count: 9),
                    spacing: 16,
                    pinnedViews: [.sectionHeaders]
                ) {
                    Section(header: header) {
                        ForEach(1..<500) {
                            Text("Cell #\($0)")
                        }
                    }
                }
            }

            Text("Other content")
                .frame(maxWidth: .infinity, minHeight: 100)
                .background(Color.yellow)
        }
    }

    var header: some View {
        LazyVGrid(
            columns: Array(repeating: GridItem(.fixed(200), spacing: 0, alignment: .center), count: 9),
            spacing: 16
        ) {
            ForEach(1..<10) {
                Text("Header \($0)")
            }
        }
        .padding(.vertical)
        .background(Color.blue)
        .foregroundColor(.white)
    }
}

So how do I get the header pinned correctly to the top?

1 Answers

did you already tried something like this:

var body: some View {
    VStack{
       Text ("My Header")
       .multilineTextAlignment(.center)
...
    }
    ScrollView(.horizontal){
        LazyVStack{
...
    }
}

First write your Text in a normal VStack and close the VStack befor using your ScrollView.

Related