I would like to implement a UI, which has
This mockup shows the intended arrangement with a 3 layer ZStack (from left to right):
This is what I got in SwiftUI:
struct TestView: View {
var body: some View {
ZStack() {
// BG Image
Image("BgImg")
.resizable()
.scaledToFill()
.frame(width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.width)
// Gradient
VStack {
Spacer()
Rectangle()
.fill(
LinearGradient(gradient: Gradient(stops: [
Gradient.Stop(color: Color(.black).opacity(0.0), location: 0),
Gradient.Stop(color: Color(.black), location: 0.5),
]), startPoint: .top, endPoint: .bottom)
)
// HOW TO GET THE RIGHT SIZE HERE?
.frame(height:500)
}
// Main UI
VStack {
// VStack 1
VStack {
Text("ABC")
Text("DEF")
}.frame(height:260)
// Fixed spacer
Spacer().frame(height:26)
// VStack 2
VStack {
Text("123").foregroundColor(.white)
Text("456").foregroundColor(.white)
}.frame(height:162)
// Variable spacer
Spacer()
// VStack 2
VStack {
Text("!!!").foregroundColor(.white)
Text("???").foregroundColor(.white)
}.frame(height:304)
}
// Fixed spacer top
.padding(.top, 26)
// Fixed spacer bottom
.padding(.bottom, 32)
}
.edgesIgnoringSafeArea(.all)
}
}
struct TestView_Previews: PreviewProvider {
static var previews: some View {
TestView()
.previewDevice("iPhone 13 Pro")
.preferredColorScheme(.light)
}
}
My questions are:
For the Image
not taking the fullscreen, you need to let that Image
ignore the safe area, not just the ZStack
;
You need to read the height
up till the end of the stack using a GeometryReader
then assign it to a value used to size the gradient.