Hi, I’m David here. I’m trying to build a table management system. On the top it’s my header
Header = Today Date, Day, Date, and refresh icon, and a book icon.
Below the Header it’s a Grid,
While first row of the the grid it’s a = Time slot
While the first column of the grid its a table of the restaurant.
The criteria i need to solve is .
When i scroll left and right, the table on the left side does show up so it help the user experience to find the table. At the same time, i need the timeslot on top to follow scroll left or right so the user will know which time slot, which table has a guest on it.
Now the problem im facing is.
The time slot doesn’t follow my main content when i scroll left or right.
When i scroll down i need the time slot to be fixed.
Here is my block code.
import SwiftUI
struct TodaysListView: View {
let cellWidth: CGFloat = 180
let cellHeight: CGFloat = 100
@State private var horizontalOffset: CGFloat = 0
var body: some View {
VStack {
// Header
HStack {
Text("Today")
.font(.title)
Text("DAY") // Replace with the actual day
.padding()
Text("DATE") // Replace with the actual date
.padding()
Image(systemName: "arrow.clockwise")
.padding()
Image(systemName: "note.text")
}
// Main content
GeometryReader { geometry in
ScrollView {
VStack(spacing: 0) {
// Fixed first row (Timeslot)
ScrollView(.horizontal, showsIndicators: false) {
LazyHStack(spacing: 0) {
Text("") // Empty cell for alignment
.frame(width: cellWidth, height: cellHeight)
.border(Color.gray)
ForEach(12..<22) { hour in
Text("\(hour):00")
.frame(width: cellWidth, height: cellHeight)
.border(Color.gray)
}
}
.background(GeometryReader {
Color.clear.preference(key: ScrollOffsetPreferenceKey.self,
value: $0.frame(in: .named("scrollView")).origin.x)
})
}
.coordinateSpace(name: "scrollView")
.frame(width: geometry.size.width)
.background(Color.white) // Background color for the fixed row
ZStack(alignment: .leading) {
ScrollView(.horizontal) {
LazyVStack(spacing: 0) {
// Remaining rows (Content)
ForEach(1..<21, id: \.self) { _ in
LazyHStack(spacing: 0) {
// Empty cell for alignment
Text("")
.frame(width: cellWidth, height: cellHeight)
.border(Color.gray)
// Remaining columns (Content)
ForEach(12..<22) { _ in
Text("")
.frame(width: cellWidth, height: cellHeight)
.border(Color.gray)
}
}
}
}
.offset(x: horizontalOffset) // Apply the same horizontal offset
}
// Fixed first column (Tables)
VStack(spacing: 0) {
ForEach(1..<21, id: \.self) { tableNumber in
Text("Table A\(tableNumber)")
.frame(width: cellWidth, height: cellHeight)
.border(Color.gray)
}
}
.background(Color.white) // Background color for the fixed column
}
}
}
}
.onPreferenceChange(ScrollOffsetPreferenceKey.self) { offset in
horizontalOffset = offset // Update the horizontal offset
}
}
}
}
struct ScrollOffsetPreferenceKey: PreferenceKey {
typealias Value = CGFloat
static var defaultValue: CGFloat = 0
static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) {
value = nextValue()
}
}
struct TodaysListView_Previews: PreviewProvider {
static var previews: some View {
TodaysListView()
}
}
Blockquote