I would like to implement a UI, which has
- a background image, which is fullscreen and scales with the device size
- a gradient above the background image and below the main UI, which is aligned bottom and it's size is dependent of the positioning of one element in the main UI
- the main UI with multiple VStacks of interface elements. There is a top area and a bottom area which are both fix aligned and sized, and a variable spacer in between
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:
- How can I size the gradient the right way?
- Why does the gradient now align to the bottom, and why does the background image not scale to fullscreen, see bottom of the preview screenshot