1

As you can see in the image below, I want the left (star) and right (sun) views’ backgrounds to fill their parent (HStack) without using GeometryReader or altering the HStack’s natural height.

Sample Image

struct FillParentTest: View {
    
    var body: some View {
        HStack(spacing: .zero) {
            Image(systemName: "star")
                .font(.title3)
                .padding()
                .background(.blue.opacity(0.5))
            
            Image(systemName: "moon")
                .resizable()
                .frame(width: 80, height: 80)
                .padding()
                .frame(maxWidth: .infinity)

            
            Image(systemName: "sun.min")
                .font(.title3)
                .padding()
                .background(.pink.opacity(0.5))
        }
        .frame(maxWidth: .infinity)
        .background(.yellow.opacity(0.5))
        .clipShape(.capsule)
        .padding(.horizontal)
    }
}
1
  • Just to be clear, you want the yellow color in the screenshot to be all covered by the blue and pink colors, each occupying half of the capsule? A screenshot of the desired result would be very helpful. Commented Nov 17 at 14:04

2 Answers 2

2

You can let children grow with maxHeight and push back the container using .fixedSize or just limit it with a simple height:

HStack(spacing: .zero) {
    Image(systemName: "star")
        .font(.title3)
        .padding()
        .frame(maxHeight: .infinity) // 👈 Here
        .background(.blue.opacity(0.5))

    Image(systemName: "moon")
        .resizable()
        .frame(width: 80, height: 80)
        .padding()
        .frame(maxWidth: .infinity)

    Image(systemName: "sun.min")
        .font(.title3)
        .padding()
        .frame(maxHeight: .infinity) // 👈 Here
        .background(.pink.opacity(0.5))
}
.fixedSize(horizontal: false, vertical: true) // 👈 And Here
.frame(maxWidth: .infinity)
.background(.yellow.opacity(0.5))
.clipShape(.capsule)
.padding(.horizontal)

Demo

Sign up to request clarification or add additional context in comments.

Comments

-1

You could consider moving the images on the left and the right to an overlay.

An overlay automatically adopts the frame of the view it is applied to. So if you apply maxHeight: .infinity to the images, their height is increased to the height of the overlay, which is the height of the underlying view.

var body: some View {
    Image(systemName: "moon")
        .resizable()
        .frame(width: 80, height: 80)
        .padding()
        .frame(maxWidth: .infinity)
        .background(.yellow.opacity(0.5))
        .overlay {
            HStack {
                Image(systemName: "star")
                    .font(.title3)
                    .padding()
                    .frame(maxHeight: .infinity)
                    .background(.blue.opacity(0.5))
                Spacer()
                Image(systemName: "sun.min")
                    .font(.title3)
                    .padding()
                    .frame(maxHeight: .infinity)
                    .background(.pink.opacity(0.5))
            }
        }
        .clipShape(.capsule)
        .padding(.horizontal)
}

With this approach, the image forming the base view (the moon) is guaranteed to be exactly in the middle of the view, it does not matter if the two side images have different widths (which in fact they do).

Screenshot

1 Comment

Ps. See this comment for some background to the downvote.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.