SwiftUI design elements

Hello everyone, for a personal project I'd like to reproduce a design element from Apple's saving application. I'd like to display three rectangles containing text: two horizontally aligned and one next to it. And I'd like the height of the last rectangle to be equal to the height of the two smallest.

Does anyone have a solution? Please provide a sample code

Answered by darkpaw in 795035022
import SwiftUI

struct ContentView: View {
    var body: some View {
		HStack {
			VStack {
				RoundedRectangle(cornerRadius: 25.0)
					.fill(Color.red)
				RoundedRectangle(cornerRadius: 25.0)
					.fill(Color.green)
			}

			VStack {
				RoundedRectangle(cornerRadius: 25.0)
					.fill(Color.blue)
			}
		}
		.frame(height: 200)
		.padding()
	}
}

#Preview {
	ContentView()
}

Accepted Answer
import SwiftUI

struct ContentView: View {
    var body: some View {
		HStack {
			VStack {
				RoundedRectangle(cornerRadius: 25.0)
					.fill(Color.red)
				RoundedRectangle(cornerRadius: 25.0)
					.fill(Color.green)
			}

			VStack {
				RoundedRectangle(cornerRadius: 25.0)
					.fill(Color.blue)
			}
		}
		.frame(height: 200)
		.padding()
	}
}

#Preview {
	ContentView()
}

In fact, I've spoken too soon @darkpaw : the layout of the rectangles is exactly what I want, but when I try to add text or elements to the rectangles, their layout changes completely. Here's my code and the rendering:

import SwiftUI

struct DashboardView: View {
    var body: some View {
        HStack {
            VStack {
                Text("Hello, World!")
                    .background(RoundedRectangle(cornerRadius: 25.0).fill(Color.red))
                    
                Text("Hello, World!")
                    .background(RoundedRectangle(cornerRadius: 25.0).fill(Color.red))
            }

            VStack {
                Text("Hello, World!")
                    .background(RoundedRectangle(cornerRadius: 25.0).fill(Color.red))
            }
        }
        .frame(height: 200)
        .padding()
    }
}

#Preview {
    DashboardView()
}

Ok I found a solution @darkpaw, with .overlay(). But I don't know if it's the best solution. Maybe there is a more optimized or "normal" way to do it. Here is the code and rendering:

import SwiftUI

struct DashboardView: View {
    var body: some View {
        HStack {
            VStack {
                RoundedRectangle(cornerRadius: 25.0)
                    .fill(Color.red)
                    .overlay(Text("Text 1").foregroundColor(.white))
                RoundedRectangle(cornerRadius: 25.0)
                    .fill(Color.green)
                    .overlay(Text("Text 2").foregroundColor(.white))
            }

            VStack {
                RoundedRectangle(cornerRadius: 25.0)
                    .fill(Color.blue)
                    .overlay{
                        VStack{
                            Spacer()
                            Text("Text 3")
                                .foregroundColor(.white)
                            Spacer()
                            Text("Text 4").foregroundColor(.white)
                            Spacer()
                        }
                        
                    }
            }
        }
        .frame(height: 200)
        .padding()
    }
}


#Preview {
    DashboardView()
}

No, that's not the best way to do what you want.

The reason you got "Hello World!" with a red background is because of this:

Text("Hello, World!")
    .background(RoundedRectangle(cornerRadius: 25.0).fill(Color.red))

You applied the .background modifier to the Text item, so just the text was given the red background.

What you want to do is use a ZStack. Just like HStack is a horizontal stack and VStack is a stack along the vertical axis, a ZStack is a stack along the z-axis.

Put a rectangle inside the ZStack and it will become the background, then you layer your content on top, i.e.:

struct DashboardView: View {
	var body: some View {
		HStack {
			VStack {
				VStack {
					ZStack {
						RoundedRectangle(cornerRadius: 25.0)
							.fill(Color.red)
						Text("Text 1")
					}
				}

				VStack {
					ZStack {
						RoundedRectangle(cornerRadius: 25.0)
							.fill(Color.green)
						Text("Text 2")
					}
				}
			}

			VStack {
				ZStack {
					RoundedRectangle(cornerRadius: 25.0)
						.fill(Color.blue)

					VStack {
						Spacer()
						Text("Text 3")
						Spacer()
						Text("Text 4")
						Spacer()
					}
				}
			}
		}
		.foregroundStyle(.white)
		.frame(height: 200)
		.padding()
	}
}

The ordering is important, for both content and modifiers. If you reverse the RoundedRectangle(...) and Text you won't see the text because the rectangle is in front of it, i.e.:

Text("Text 1")
RoundedRectangle(cornerRadius: 25.0)
	.fill(Color.red)

By the way, .foregroundColor() is deprecated. While it works now, it will be removed in a later version of the OS, so you should move to the new foregroundStyle() modifier instead.

Also note that if all your text inside those rectangles is going to be the same colour, you can add that modifier to the top-level HStack, as I have done above.

SwiftUI design elements
 
 
Q