You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI登录界面:如何让VStack填充剩余空白空间?

SwiftUI登录界面VStack填充剩余空白区域问题解决

问题原因

ZStack的子视图默认仅适配自身内容尺寸,你的第二个VStack没有占据ZStack的全部可用高度,导致内部添加的Spacer()无法获得足够空间调整布局,反而让内容被挤到顶部。

解决步骤

  1. 给第二个VStack添加.frame(maxHeight: .infinity),让它填充ZStack的全部可用高度。
  2. 在第二个VStack内部的表单内容上方(或上下)添加Spacer(),利用它填充空白区域,将表单内容调整到目标位置。

修改后的完整代码

struct loginView: View {
    @State private var stringOfTextField: String = String()
    
    var body: some View {
        ZStack {
            LinearGradient(colors: [Color("primarycolor"), Color("secondarycolor")],
                           startPoint: .top,
                           endPoint: .center).ignoresSafeArea()
            
            VStack() {
                Text("Login").foregroundColor(.white).font(
                    .system(size: 18)
                )
                Image("logo")
                Spacer()
            }
            
            VStack{
                Spacer() // 顶部空白填充,将表单内容往下推
                
                TextField("Enter Email", text: $stringOfTextField)
                    .padding()
                    .overlay(RoundedRectangle(cornerRadius: 10.0).strokeBorder(Color.gray, style: StrokeStyle(lineWidth: 1.0)))
                    .padding(.bottom)
                
                TextField("Enter Password", text: $stringOfTextField)
                    .padding()
                    .overlay(RoundedRectangle(cornerRadius: 10.0).strokeBorder(Color.gray, style: StrokeStyle(lineWidth: 1.0)))
                    .padding(.bottom)
                
                Text("Forgot Password ?")
                    .frame(maxWidth: .infinity, alignment: .trailing)
                    .padding(.bottom)
                
                Button(action: {
                    print("sign up bin tapped")
                }) {
                    Text("SIGN IN")
                        .frame(minWidth: 0, maxWidth: .infinity)
                        .font(.system(size: 18))
                        .padding()
                        .foregroundColor(.white)
                        .overlay(
                            RoundedRectangle(cornerRadius: 10)
                                .stroke(Color("secondarycolor"), lineWidth: 1)
                        )
                }
                .background(Color("secondarycolor"))
                .cornerRadius(25)
                
                Spacer() // 底部空白填充,让表单内容居中(可选,按需调整)
            }
            .frame(maxHeight: .infinity) // 关键:让VStack占满ZStack可用高度
            .padding(.vertical, 60)
            .padding(.horizontal, 20)
            .background(Color.white)
            .cornerRadius(30)
        }
    }
}

说明

  • .frame(maxHeight: .infinity) 确保第二个VStack的高度扩展到ZStack的整个可用空间,为Spacer()提供了填充空白的基础。
  • 可根据需求调整VStack内部Spacer()的位置和数量:仅保留顶部Spacer()会把表单内容推至屏幕底部;上下都添加则让表单居中。

内容的提问来源于stack exchange,提问作者rameez khan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 21:55:30