I want to transform a web app into an iOS app and I am struggling with alignments and the GeometryReader().
This a a screenshot from my original web app template:
This is my current version in SwiftUI:
With the related code:
struct PileRow: View {
var body: some View {
HStack() {
VStack(alignment: .leading, spacing: 3) {
Text("Adobe".uppercased())
Bar(backgroundColor: Color.gray, width: 200)
Bar(backgroundColor: Color.black, width: 200)
HStack(alignment: .top, spacing: 3) {
Text("EUR 1,00")
.fontWeight(.light)
Text(" / ")
.fontWeight(.light)
.foregroundColor(Color.gray)
Text("35,69")
.fontWeight(.light)
.foregroundColor(Color.gray)
}
Image("dots")
.resizable()
.scaledToFit()
.frame(width: 20)
}
.font(.system(size: 14))
.padding()
}
.background(Color.white)
.cornerRadius(15)
.shadow(radius: 6, x: 5, y: 5)
}
}
struct Bar: View {
var backgroundColor: Color
var width: CGFloat
var body: some View {
Rectangle()
.fill(backgroundColor)
.frame(width: width, height: 3)
.cornerRadius(1.5)
}
}
I want:
- the dots image to be centered in the parent VStack (like margin: 0 auto; in CSS)
- the outer HStack to be 100% width with a left and right margin of 10px (like width: 100%; margin: auto 10px; in CSS)
The special challenge I want to realize is, to give the second Bar() view a percentage with (or some equivalent) to have a with of 1.00/35.69*100%.
In the apple documentation of Swift UI I found:
GeometryReader A container view that defines its content as a function of its own size and coordinate space. 3
With a change from:
Bar(backgroundColor: Color.gray, width: 200)
Bar(backgroundColor: Color.black, width: 200)
to
GeometryReader { g in
Bar(backgroundColor: Color.gray, width: g.size.width)
}
.frame(height: 3)
GeometryReader { g in
Bar(backgroundColor: Color.black, width: g.size.width*(1/35.69))
}
.frame(height: 3)
it is going close to what I look for:
I don't understand what is happening here. My purpose was to give the Bar views a size relationship to the parent. But the parent itself gets a different width and hight that I need to fix with a frame with a height of 3 and the parent HStack fills the entire screen.
When I try this:
GeometryReader { g in
Bar(backgroundColor: Color.gray, width: g.size.width)
Bar(backgroundColor: Color.black, width: g.size.width*(1/35.69))
}
I am completely out, because the bars get somehow vstacked: