Search code examples
swiftuivstackzstack

SwiftUI: Spacers won't scale down because BG Image will not adjust to device size


I use a ZStack to display a fullscreen background image underneath the main UI. The main UI consists of a VStack with multiple views separated by flexible Spacers to scale down or up on different device sizes. Now I experience that the Spacers will not scale down on small devices because the background image on small devices remains bigger than the screen size and keeps the ZStack tall, see screenshot of the preview of iPhone 8. What am I doing wrong here?

Code:

import SwiftUI

struct TestView: View {
    
    var headerView: some View {
        VStack {
            Text("HEADER").padding([.leading,.trailing], 100)
        }
    }
    
    var middleView: some View {
        HStack {
            Text("MIDDLE").padding([.leading,.trailing], 100)
        }
    }
    
    var bottomView: some View {
        VStack {
            Text("BOTTOM").padding([.leading,.trailing], 100)
        }
    }
    
    var body: some View {
        ZStack {
            // Background Image
            Image("BgImg")
                .resizable()
                .aspectRatio(contentMode: .fill)
                .edgesIgnoringSafeArea(.all)
            
            // Main UI
            VStack(spacing: 0) {
                headerView
                    .frame(height:222)
                    .background(Color.red)
                
                Spacer()
                
                middleView
                    .frame(height:155)
                    .background(Color.orange)
                
                Spacer()
                
                bottomView
                    .frame(height:288)
                    .background(Color.yellow)
            }
            .padding(.bottom, 32)
            .padding(.top, 54)
            // END Main UI
        }
        .edgesIgnoringSafeArea(.all)
        .statusBar(hidden: true)
        // END ZStack
    }
}

Preview Screenshot: See blue border is bigger than device enter image description here

BG Image: enter image description here


Solution

  • In described scenario you need to use .background instead of ZStack, such so main view form needed full-screen layout and image in background will not affect it.

    So the layout should be like

    VStack(spacing: 0) {
    
       // content here
    
    }
    .padding(.bottom, 32)
    .padding(.top, 54)
    .edgesIgnoringSafeArea(.all)
    .statusBar(hidden: true)
    .background(
    
         // image here
    
    )