I have been experimenting with LazyVGrid to produce a table with grid lines. I'm using XCode 13.4 & iOS15. Everything seemed to be going well until I parameterized all the column sizes, line widths, etc. The content consists of an array of row data with 5 pieces of text in each row. Here is the code:
struct StatisticsView: View {
private let columnMinWidths: [CGFloat] = [120, 50, 50, 50, 50]
private let rowHeight: CGFloat = 40
private let thinGridlineSize: CGFloat = 0.5
private let thickGridlineSize: CGFloat = 2
private let lineColour = Color.accentColor
private let columns: [GridItem]
private let rowContents = [
["Player's name", "Graham", "John", "Archie", ""],
["Round 1", "2", "3", "1", ""],
["Round 2", "3", "-", "2", ""],
["Round 3", "1", "2", "4", ""],
["Round 4", "2", "1", "1", ""]
]
init() {
self.columns = [
GridItem(.fixed(thickGridlineSize), spacing: 0),
GridItem(.flexible(minimum: columnMinWidths[0]), spacing: 0),
GridItem(.fixed(thickGridlineSize), spacing: 0),
GridItem(.flexible(minimum: columnMinWidths[1]), spacing: 0),
GridItem(.fixed(thinGridlineSize), spacing: 0),
GridItem(.flexible(minimum: columnMinWidths[2]), spacing: 0),
GridItem(.fixed(thinGridlineSize), spacing: 0),
GridItem(.flexible(minimum: columnMinWidths[3]), spacing: 0),
GridItem(.fixed(thinGridlineSize), spacing: 0),
GridItem(.flexible(minimum: columnMinWidths[4]), spacing: 0),
GridItem(.fixed(thickGridlineSize), spacing: 0),
]
}
var body: some View {
VStack(spacing: 0) {
// top horizontal gridline
lineColour.frame(height: thickGridlineSize)
LazyVGrid(columns: columns, alignment: .leading, spacing: 0) {
ForEach(0..<rowContents.count, id: \.self) { row in
lineColour.frame(height: rowHeight)
ForEach(0..<rowContents.first!.count, id: \.self) { col in
// cell contents with bottom gridline
VStack(spacing: 0) {
Text(rowContents[row][col])
.font(.caption2)
.frame(height: rowHeight - thinGridlineSize)
// tried using a colour fill but same result
// Color.green
// .frame(height: rowHeight - thinGridlineSize)
lineColour.frame(height: thinGridlineSize)
}
// vertical gridline between cells
lineColour.frame(height: rowHeight)
}
}
}
// bottom horizontal gridline
lineColour.frame(height: thickGridlineSize)
}
.padding(.horizontal, 8)
}
}
and here is what is being displayed on the simulator screen:
Can anyone see where I'm going wrong here? Any help would be much appreciated. Thanks.
You have to remove id: \.self
from both loops. View Id become duplicated so it's not drawing more than one line.