Home > database >  How Do I get uniform view size when using Image and SFSymbols in SwiftUI?
How Do I get uniform view size when using Image and SFSymbols in SwiftUI?

Time:11-07

Here is my View:

InconsistentSymbolSizes

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))
    }
}

enter image description here

  • Related