1

I am currently trying to implement a spreadsheet like view (I found this, but it's not in SwiftUI https://github.com/bannzai/SpreadsheetView) and am following this SO (SwiftUI: Pin headers in scrollview which has vertical and horizontal scroll in excel like view) which is working on iOS14, but it breaks on iOS16.

when executed on ios14 simulator, the Initial Offset on Console is (0.0,0.0) and the scrollview would be at the correct location (Row1, Co1). However, the same code, when executed on iOS16, the offset changes to another number eg: (-300.22,0.0) and the resultant view will show at say (Row1,Col16)

Q: How can I get the same behaviour back?

I have tried to use onAppear and putting the CGPoint.Zero coordinate to push it back to the origin but it's not working..

Tx enter image description hereenter image description here

The code is per below:

struct ContentView: View {

let columns = 20
let rows = 30

@State private var offset = CGPoint.zero

var body: some View {
    
    HStack(alignment: .top, spacing: 0) {
        
        VStack(alignment: .leading, spacing: 0) {
            // empty corner
            Color.clear.frame(width: 70, height: 50)
            ScrollView([.vertical]) {
                rowsHeader
                    .offset(y: offset.y)
            }
            .disabled(true)
        }
        VStack(alignment: .leading, spacing: 0) {
            ScrollView([.horizontal]) {
                colsHeader
                    .offset(x: offset.x)
            }
            .disabled(true)

            table
                .coordinateSpace(name: "scroll")
        }
    }
    .padding()
}

var colsHeader: some View {
    HStack(alignment: .top, spacing: 0) {
        ForEach(0..<columns) { col in
            Text("COL \(col)")
                .foregroundColor(.secondary)
                .font(.caption)
                .frame(width: 70, height: 50)
                .border(Color.blue)
        }
    }
}

var rowsHeader: some View {
    VStack(alignment: .leading, spacing: 0) {
        ForEach(0..<rows) { row in
            Text("ROW \(row)")
                .foregroundColor(.secondary)
                .font(.caption)
                .frame(width: 70, height: 50)
                .border(Color.blue)
        }
    }
}

var table: some View {
    ScrollView([.vertical, .horizontal]) {
        VStack(alignment: .leading, spacing: 0) {
            ForEach(0..<rows) { row in
                HStack(alignment: .top, spacing: 0) {
                    ForEach(0..<columns) { col in
                        // Cell
                        Text("(\(row), \(col))")
                            .frame(width: 70, height: 50)
                            .border(Color.blue)
                            .id("\(row)_\(col)")
                    }
                }
            }
        }
        .background( GeometryReader { geo in
            Color.clear
                .preference(key: ViewOffsetKey.self, value: geo.frame(in: .named("scroll")).origin)
        })
        .onPreferenceChange(ViewOffsetKey.self) { value in
            print("offset >> \(value)")
            offset = value
        }
    }
  }
}

struct ViewOffsetKey: PreferenceKey {
  typealias Value = CGPoint
  static var defaultValue = CGPoint.zero
  static func reduce(value: inout Value, nextValue: () -> Value) {
      value.x += nextValue().x
      value.y += nextValue().y
  }
}
app4g
  • 670
  • 4
  • 24

0 Answers0