I'm running into a kind of a conundrum with a seemingly simple problem...
My view has a content with a smaller width than height, and I wish to have it displayed within a nice square card.
Here's what I've done here:
struct SquareView: View {
var body: some View {
VStack {
Image(systemName: "globe")
.font(.system(size: 100))
.padding()
.foregroundColor(.red)
Text("Yo !")
.font(.title)
.fontWeight(.bold)
.foregroundColor(.orange)
}
.aspectRatio(contentMode: .fill) // Same result with or without this line
.padding()
.background(Color.white.opacity(0.5))
.cornerRadius(16)
}
}
struct SquareView_Previews: PreviewProvider {
static var previews: some View {
SquareView()
.padding(30)
.background(.yellow)
}
}
But the aspectRatio
bit seems to have absolutely no effect on the square part I wish to achieve.
After looking up for a solution, it seems that ZStack
was to be my savior...
Ok, then, here's what I did, and I almost succeeded:
struct SquareView: View {
var body: some View {
ZStack {
Rectangle()
.foregroundColor(Color.white.opacity(0.5))
.aspectRatio(contentMode: .fill)
.cornerRadius(16)
VStack {
Image(systemName: "globe")
.font(.system(size: 100))
.padding()
.foregroundColor(.red)
Text("Yo !")
.font(.title)
.fontWeight(.bold)
.foregroundColor(.orange)
}
.padding()
}
.fixedSize()
}
}
And lo!
It's square, all right, but the size of the ZStack
does not seem to take into account the Rectangle
, as it is confirmed when it is selected in Xcode:
So the only solution seems to be one involving GeometryReader
and pride makes me refuse this remain of the old age!
I'm sure, someone out there knows there is another way, I'm certain to be quite close... Any help on this matter would be greatly appreciated!
EDIT: I've put the whole file in the example, instead of just the content.
EDIT 2: Here's the complete solution for my example thanks to @Paulw11's answer.
struct SquareView: View {
var body: some View {
VStack {
Image(systemName: "globe")
.font(.system(size: 100))
.padding()
.foregroundColor(.red)
Text("Yo !")
.font(.title)
.fontWeight(.bold)
.foregroundColor(.orange)
}
.padding()
.background {
Rectangle()
.aspectRatio(contentMode: .fill)
.foregroundColor(.white.opacity(0.5))
.cornerRadius(16)
}
}
}
CodePudding user response:
You can simply set a background for your existing content and give it a negative inset:
struct CardView: View {
var body: some View {
ContentView()
.background(
Rectangle()
.inset(by:-30)
.aspectRatio(1.0, contentMode:.fill)
.foregroundColor(.yellow)
)
}
}