Lazy loading SwiftUI grid sheet both vertically and horizontally

89 views Asked by At

I tried to build a grid view that loads lazily on both vertical and horizontal axes, the main goal is building a calendar for a list of employees. Both the list and the calendar interval can be very large so they have to be rendered lazily. I've tried LazyHGrid and LazyVGrid but they only render views lazily on one direction. The further approach uses one LazyVStack for the whole view and one LazyHStack for each row, the loading is lazy (check print in the console) but while scrolling the views, it loses their position and the grid gets broken. I also need fixed headers, that is achieved in the code using pinnedViews.

struct ContentView: View {
    var body: some View {
        ScrollView([.horizontal, .vertical]) {
            LazyVStack(spacing: 20, pinnedViews: .sectionHeaders) {
                Section(header: columnHeaders) {
                    ForEach(0..<20) { row in
                        LazyHStack(spacing: 20, pinnedViews: .sectionHeaders) {
                            Section(header: rowHeader(with: "Employee \(row)")) {
                                ForEach(0..<100) { column in
                                    Text("Cell \(row), \(column)")
                                        .foregroundColor(.white)
                                        .font(.largeTitle)
                                        .frame(width: 200, height: 100)
                                        .background(Color.red)
                                        .onAppear {
                                            print("Cell \(row), \(column)")
                                        }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    
    var columnHeaders: some View {
        LazyHStack(spacing: 20, pinnedViews: .sectionHeaders) {
            Section(header: rowHeader(with: "")) {
                ForEach(0..<100) { column in
                    Text("Header \(column)")
                        .frame(width: 200, height: 100)
                        .background(Color.white)
                }
            }
        }
    }
    
    func rowHeader(with label: String) -> some View {
        Text(label)
            .frame(width: 100, height: 100)
            .background(Color.white)
    }
}

Lazy Grid

Tried what was said above.

0

There are 0 answers