Is there a way that the columns in this view could be aligned left? So that each row wouldn’t necessarily be the same number of columns?
Here is how it currently lays out:
And here is the code:
struct SizeSelectorView: View {
@State private var selectedSize: String = "medium"
let test = ["small", "medium", "large", "xlarge", "xxlarge"]
let adaptiveColumns = [
GridItem(.adaptive(minimum: 100))
]
var body: some View {
ScrollView {
LazyVGrid(columns: adaptiveColumns, alignment: .leading, spacing: 8) {
ForEach(test, id: .self) { size in
Text(size)
.font(.system(size: 14))
.foregroundColor(selectedSize == size ? .black : .white)
.padding([.top, .bottom], 10)
.padding([.leading, .trailing], 16)
.background(selectedSize == size ? Color.red : Color.gray2)
.cornerRadius(16, corners: .allCorners)
.tag(size)
.onTapGesture {
selectedSize = size
}
}
}
}
}
}
Is there a better way to do this besides LazyVGrid? I’d like each row of items to fit/align to the leading edge and truncate to the next row once an item doesn’t fit.
Like
“small” “medium” “large” Spacer()
“xlarge” “xxlarge” Spacer()
So that each row wouldn’t necessarily be the same number of columns?
While you can set the number of columns a view occupies by using gridCellColumns
, I suspect you don’t want the views to occupy a fixed number of columns, and instead flow like multi-line text.
That is, by definition, not a Grid
.
You need a different layout to achieve something like that. For example, the SwiftUI-Flow package offers a layout like that.
Usage example:
let test = ["small", "medium", "large", "xlarge", "xxlarge", "foo", "bar", "baz"]
var body: some View {
ScrollView {
HFlow {
ForEach(test, id: .self) { size in
Text(size)
.font(.system(size: 14))
.foregroundColor(selectedSize == size ? .black : .white)
.padding([.top, .bottom], 10)
.padding([.leading, .trailing], 16)
.background(selectedSize == size ? Color.red : Color.gray)
.cornerRadius(16)
.tag(size)
.onTapGesture {
selectedSize = size
}
}
}
}
}
Output:
You can also set the item spacing, row spacing etc.
0