How to align views inside HStack according to view in VStack?

49 Views Asked by At

Let's say we have the following code:

struct ContentView: View {
    var body: some View {
        VStack {
            Color.black
                .frame(width: 130, height: 30)
            
            HStack(spacing: 17) {
                ChildView()
                
                ChildView()
                
                ChildView()
                
                ChildView()
            }
        }
    }
}

struct ChildView: View {
    var body: some View {
        VStack(spacing: 2) {
            Color.red
                .frame(width: 15, height: 15)
            
            Text("Title")
                .font(.system(size: 10))
        }
    }
}

actual result is: enter image description here

I want to stretch my HStack so that the first ChildView is aligned to the left edge of the red square and black rectangle, and the last one is aligned to the right edge of the red square and black rectangle. Like this: enter image description here

I'm guessing it's possible to make a layout like this using custom alignmentGuide, but i'm stuck on it.

1

There are 1 best solutions below

0
Benzy Neez On

You can achieve this layout with the following changes to the code:

  1. Apply the constraining width to the VStack containing the black color and the HStack and apply maxWidth: .infinity to the black color.

  2. Set the spacing for the HStack to 0.

  3. Add a Spacer between each of the items in the HStack.

  4. Use a hidden placeholder to reserve vertical space for the labels.

  5. Show the actual labels as an overlay, so that they do not impact the layout.

Like this:

struct ContentView: View {
    var body: some View {
        VStack {
            Color.black
                .frame(height: 30)
                .frame(maxWidth: .infinity)

            HStack(spacing: 0) {
                ChildView()
                Spacer()
                ChildView()
                Spacer()
                ChildView()
                Spacer()
                ChildView()
            }
        }
        .frame(width: 130)
    }
}

struct ChildView: View {
    var body: some View {
        VStack(spacing: 2) {
            Color.red
                .frame(width: 15, height: 15)
            Text(".").hidden()
        }
        .overlay(alignment: .bottom) {
            Text("Title")
                .fixedSize()
        }
        .font(.system(size: 10))
    }
}

Screenshot