Skip to content

Instantly share code, notes, and snippets.

@ole
Last active September 20, 2022 16:46
Show Gist options
  • Save ole/4a8b5fe49d53c79b34e22b3401872093 to your computer and use it in GitHub Desktop.
Save ole/4a8b5fe49d53c79b34e22b3401872093 to your computer and use it in GitHub Desktop.
// SwiftUI question: How do you put a continuous background behind a GridRow?
//
// I would have thought:
//
// GridRow { … }
// .background { … }
//
// But this puts the background behind each cell individually (behaves like Group),
// which is not what I want.
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)
// Adding `.frame(maxWidth: .infinity)` on the individual cells
// makes it work (kind of), but changes the layout in other ways.
// .frame(maxWidth: .infinity, alignment: .leading)
Text(item.population)
.monospacedDigit()
.padding(.vertical, 4)
.padding(.horizontal, 24)
// .frame(maxWidth: .infinity, alignment: .trailing)
Text(item.area)
.monospacedDigit()
.padding(4)
// .frame(maxWidth: .infinity, alignment: .trailing)
}
.foregroundColor(isEven ? .white : nil)
.background(isEven ? Color.accentColor : nil)
}
}
.border(Color.accentColor)
}
.padding()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
import PlaygroundSupport
let liveView = ContentView()
.frame(width: 400, height: 600)
PlaygroundPage.current.setLiveView(liveView)
@ole
Copy link
Author

ole commented Sep 20, 2022

This is how it looks with GridRow { … }.background { … }:

Screen Shot 2022-09-20 at 11 25 45

I want the gaps in the background to go away. You can experiment with adding things like .frame(maxWidth: .infinity) to the grid cells to make them grow wider, but that changes the layout in other ways, e.g. it makes cells wider than they have to be and changes the space distribution between the columns.

For example, this is the result when I add frame(maxWidth: .infinity, alignment: .leading) (or .trailing, respectively) to each individual cell:

2022-09-20-SwiftUI-GridRow-background-frame-maxWidth

Notice two changes:

  1. The grid now takes up the entire available width.
  2. The width distribution of the columns has changed. The second and third columns are too wide (for my taste).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment