Does anybody know learn how to implement a view (desk/grid/assortment) like these?
I’ve been at it for some time now and can’t determine it out. I am fairly new to Swift which has not helped, however primarily the desk needs to be horizontally and vertically scrollable (however not concurrently, so there should not be any “diagonal” scrolling), and will have a pinned header row (which “pushes” on the finish of the desk) and a pinned column.
I’ve seen this in two totally different apps which makes me suppose it needs to be comparatively easy however I can not appear to get it proper. I’ve been utilizing SwiftUI however possibly it’s simply too advanced and I have to fall again to UIKit.
Right here is one thing that feels shut:
import SwiftUI
struct Group {
let teamId: Int
let metropolis: String
let title: String
}
struct ScrollableTableView: View {
@State personal var groups = [
Team(teamId: 1610612737, city: "Atlanta", name: "Hawks"),
Team(teamId: 1610612738, city: "Boston", name: "Celtics"),
Team(teamId: 1610612739, city: "Cleveland", name: "Cavaliers"),
Team(teamId: 1610612740, city: "New Orleans", name: "Pelicans")
]
var physique: some View {
let columns = [
GridItem(.fixed(120), alignment: .leading), // Pinned first column
GridItem(.fixed(150), alignment: .leading),
GridItem(.fixed(200), alignment: .leading)
]
ScrollView([.vertical], showsIndicators: true) {
ZStack {
ScrollView([.horizontal]) {
LazyVGrid(columns: columns, alignment: .main, pinnedViews: [.sectionHeaders]) {
// Pinned Header Part
Part(header: headerView) {
// Desk Rows
ForEach(groups) { crew in
Part(header: Textual content("") // Pinned column
.body(peak: 40)
.padding(.horizontal, 4)) {
Textual content(crew.metropolis)
.body(peak: 40)
.padding(.horizontal, 4)
.border(Coloration(.separator), width: 0.5)
Textual content(crew.title)
.body(peak: 40)
.padding(.horizontal, 4)
.border(Coloration(.separator), width: 0.5)
}
.background(Coloration(.systemBackground))
}
}
}
}
LazyVGrid(columns: [columns[0]], alignment: .main, pinnedViews: [.sectionHeaders]) {
Part(header: Textual content("Group ID")
.body(width: 120, peak: 40, alignment: .main)
.daring()
.padding(.horizontal, 4)
.background(Coloration(.systemGray5))
.border(Coloration(.separator), width: 0.5)) {
ForEach(groups) { crew in
Textual content(String(crew.teamId)) // Pinned column
.body(width: 120, peak: 40)
.padding(.horizontal, 4)
.background(Coloration(.systemGray6))
.border(Coloration(.separator), width: 0.5)
}
}
}
}
}
.border(Coloration(.separator), width: 1)
}
personal var headerView: some View {
HStack(spacing: 0) {
Textual content("")
.body(width: 120, peak: 40, alignment: .main)
.daring()
.padding(.horizontal, 4)
.background(Coloration(.systemGray5))
.border(Coloration(.separator), width: 0.5)
Textual content("Metropolis")
.body(width: 150, peak: 40, alignment: .main)
.daring()
.padding(.horizontal, 4)
.background(Coloration(.systemGray5))
.border(Coloration(.separator), width: 0.5)
Textual content("Identify")
.body(width: 200, peak: 40, alignment: .main)
.daring()
.padding(.horizontal, 4)
.background(Coloration(.systemGray5))
.border(Coloration(.separator), width: 0.5)
}
.background(Coloration(.systemGray5))
}
}
#Preview {
ScrollableTableView()
}