4

Desired output

Looking for a way to split an HStack in uneven elements, one taking over 1/2 of the screen and the other two 1/4 of the screen (see attachment).

Code:

 struct MyCategoryRow: View { var body: some View { VStack(alignment: .leading, spacing: 0) { HStack(spacing: 0) { ForEach(0...2, id: \.self) { block in ColoredBlock() }.frame(minWidth: 0, maxWidth: .infinity, alignment: Alignment.topLeading) } } } 

So the above code results in an HStack with 3 colored blocks of equal width. I tried enforcing width using UIScreen.main.bounds.width but that approach doesn't adapt to change in orientation. I also tried using GeometryReader like so:

 GeometryReader { g in ColoredBlock().frame(width: block == 0 ? g.size.width * 2 : g.size.width / 2) } 

But that didn't work either, seems like the fact that every ColoredBlock will take up 1/3 of the HStack is decided beforehand.

Update with layoutPriority attempt:

struct MyCategoryRow: View { var body: some View { VStack(alignment: .leading, spacing: 0) { HStack(spacing: 0) { ForEach(0...2, id: \.self) { block in ColoredBlock(background: (block == 0) ? Constants.pastel1 : Constants.pastel2).layoutPriority(block == 0 ? 1.0 : 0.5) }.frame(minWidth: 0, maxWidth: .infinity, alignment: Alignment.topLeading) } } } struct ColoredBlock: View { let background: Color var body: some View { GeometryReader { geometry in VStack(spacing: 0){ HStack { Text("Some text").padding(.horizontal, 15).padding(.top, 15) }.frame(alignment: .leading) VStack(alignment: .leading){ Text("Some more text").font(.subheadline).fontWeight(.light) }.padding(.vertical, 10).padding(.horizontal, 15) }.background(self.background) .cornerRadius(15) } } } 

Result:

2 Answers 2

0

I think what you need is .layoutPriority. Set it to 1.0 for the first block and 0.5 for the second and third blocks.

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

1 Comment

Thanks! Updated my question above with my attempt to implement your suggestion. Result was the first block is now taking up about 90% of the screen. Added code for ColoredBlock as well, maybe I'm doing something wrong there.
0

What I ended up doing was using GeometryReader in MyCategoryRow instead of ColoredBlock and passing width to ColoredBlock

HStack { ForEach(0...2, id: \.self) { block in ColoredBlock(background: (block == 0) ? Constants.pastel1 : Constants.pastel2, width: block == 0 ? geometry.size.width / 2 : geometry.size.width / 4, height: 150.0) } } 

This works, though now I find myself having to specify a height which I'd prefer not to hardcode. If anyone has a better solution, please let me know!

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.