Here is my View:
I want all boxes (the red rectangles) to be the same size (heights all equal to each other and widths all equal to each other). They don't need to be square.
When I create views using Image(systemname:) they have different intrinsic sizes. How do I make them the same size without hard-coding the size.
struct InconsistentSymbolSizes: View {
let symbols = [ "camera", "comb", "diamond", "checkmark.square"]
var body: some View {
HStack(spacing: 0) {
ForEach(Array(symbols), id: \.self) { item in
VStack {
Image(systemName: item).font(.largeTitle)
}
.padding()
.background(.white)
.border(.red)
}
}
.border(Color.black)
}
}
CodePudding user response:
If you want to normalize the sizes, you could use a PreferenceKey
to measure the largest size and make sure that all of the other sizes expand to that:
struct ContentView: View {
let symbols = [ "camera", "comb", "diamond", "checkmark.square"]
@State private var itemSize = CGSize.zero
var body: some View {
HStack(spacing: 0) {
ForEach(Array(symbols), id: \.self) { item in
VStack {
Image(systemName: item).font(.largeTitle)
}
.padding()
.background(GeometryReader {
Color.clear.preference(key: ItemSize.self,
value: $0.frame(in: .local).size)
})
.frame(width: itemSize.width, height: itemSize.height)
.border(.red)
}.onPreferenceChange(ItemSize.self) {
itemSize = $0
}
}
.border(Color.black)
}
}
struct ItemSize: PreferenceKey {
static var defaultValue: CGSize { .zero }
static func reduce(value: inout Value, nextValue: () -> Value) {
let next = nextValue()
value = CGSize(width: max(value.width,next.width),
height: max(value.height,next.height))
}
}