Skip to content

Instantly share code, notes, and snippets.

@auramagi
Created September 20, 2022 12:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save auramagi/737df2e04e082b995150927f0bfc56a1 to your computer and use it in GitHub Desktop.
Save auramagi/737df2e04e082b995150927f0bfc56a1 to your computer and use it in GitHub Desktop.
// RE:
// https://gist.github.com/ole/4a8b5fe49d53c79b34e22b3401872093
// https://mobile.twitter.com/olebegemann/status/1572163020695928832
import SwiftUI
struct Item: Identifiable {
var id: UUID = .init()
var country: String
var population: String
var area: String
}
let sampleItems: [Item] = [
Item(country: "China", population: "1,413", area: "9,597"),
Item(country: "India", population: "1,376", area: "3,287"),
Item(country: "United States", population: "332", area: "9,525"),
Item(country: "Indonesia", population: "276", area: "1,905"),
Item(country: "Pakistan", population: "229", area: "882"),
Item(country: "Nigeria", population: "217", area: "924"),
Item(country: "Brazil", population: "215", area: "8,516"),
]
struct ContentView: View {
var body: some View {
VStack(spacing: 32) {
VStack(alignment: .leading, spacing: 24) {
Text("How do you put a continuous background behind a GridRow?")
Text("`GridRow { … }.background { … }` puts the background behind each cell individually (behaves like Group), which is not what I want.")
}
.multilineTextAlignment(.leading)
Grid(alignment: .trailing, horizontalSpacing: 0, verticalSpacing: 0) {
ForEach(Array(zip(sampleItems, 0...)), id: \.0.id) { item, idx in
let isEven = idx.isMultiple(of: 2)
GridRow {
Text(item.country)
.padding(4)
.gridColumnAlignment(.leading)
.fixedSize(horizontal: false, vertical: true)
Text(item.population)
.monospacedDigit()
.padding(.vertical, 4)
.padding(.horizontal, 24)
Text(item.area)
.monospacedDigit()
.padding(4)
}
.foregroundColor(isEven ? .white : nil)
.background {
GeometryReader { proxy in
Color.clear
.preference(key: GridRowHeightPreferenceKey<Int>.self, value: [idx: proxy.size.height])
}
}
}
}
.border(Color.accentColor)
.backgroundPreferenceValue(GridRowHeightPreferenceKey<Int>.self) { heights in
VStack(spacing: .zero) {
ForEach(0..<sampleItems.count, id: \.self) { idx in
let isEven = idx.isMultiple(of: 2)
Group {
if isEven {
Color.accentColor
} else {
Color.clear
}
}
.frame(height: heights[idx, default: 0])
}
}
}
}
.padding()
}
}
struct GridRowHeightPreferenceKey<ID: Hashable>: PreferenceKey {
static var defaultValue: [ID: CGFloat] { [:] }
static func reduce(value: inout [ID: CGFloat], nextValue: () -> [ID: CGFloat]) {
nextValue().forEach {
value[$0] = max(value[$0, default: 0], $1)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment