5

I need to make a SwiftUI view that can be scrolled both vertically and horizontally, with multiple columns, where the leftmost ones don't scroll horizontally, but the following ones do.

Think like a spreadsheet with some frozen header columns.

I've got something working, kinda. The GIF shows when scrolling vertically it moves all of the cells, and scrolling horizontally only scrolls the "custom" cells.

However, I'd also like to have a frozen header row, like a Mac table view's column headings, that remains floating at the top, aligned with the fixed and horizontally scrolling columns of the rows below. I haven't figured that one out yet.

enter image description here

Here's my prototype code:

        ScrollView  {
            ZStack(alignment: .leading) {
                ScrollView (.horizontal) {
                    LazyVStack(spacing: 20) {
                        ForEach(0..<20) { row in
                            LazyHStack(spacing: 20) {
                                Text("")
                                    .frame(width: 250, height: 200)
                                    .background(Color.clear)
                                
                                ForEach(0..<10) { column in
                                    Text("Custom \(row), \(column)")
                                        .foregroundColor(.white)
                                        .font(.largeTitle)
                                        .frame(width: 200, height: 200)
                                        .background(Color.red)
                                }
                            }
                        }
                    }
                }
                
                VStack(spacing: 20) {
                    ForEach(0..<20) { row in
                        HStack(spacing: 2) {
                            Text("\(row)")
                                .foregroundColor(.yellow)
                                .font(.largeTitle)
                                .frame(width: 50, height: 200)
                                .background(Color.blue)
                            
                            Text("Fixed \(row)")
                                .foregroundColor(.yellow)
                                .font(.largeTitle)
                                .frame(width: 200, height: 200)
                                .background(Color.blue)
                        }
                    }
                }
            }
        }

I'm a newbie at SwiftUI, so perhaps I'm missing something obvious. Any advice much appreciated!

Dejal
  • 813
  • 6
  • 18
  • Probably achievable with the [SwiftUI-Introspect](https://github.com/siteline/SwiftUI-Introspect) package. I would recommend it for more complex UIs to drop down into UIKit. I can write an answer with it if you're fine with that. – George Apr 10 '22 at 00:02
  • I would prefer a pure SwiftUI solution, if possible, but given the lack of answers, that may not be feasible. So I would be interested in a SwiftUI-Introspect solution, if you'd like to write it up. – Dejal Apr 10 '22 at 23:20
  • how about this https://stackoverflow.com/questions/71122712/swiftui-pin-headers-in-scrollview-which-has-vertical-and-horizontal-scroll-in-e – app4g Feb 03 '23 at 19:48
  • @Dejal did you find the solution for it? I'm trying to do the same but not success yet – John Lima Aug 09 '23 at 16:42
  • No. I ended up going with a UICollectionView in this case, for other reasons. – Dejal Aug 24 '23 at 15:36

0 Answers0