当嵌入 SwiftUI 中的 ScrollView 中时,VStack 中的内容会缩小

Content inside VStack shrinks when embedded inside a ScrollView in SwiftUI

我有一个简单的登录屏幕,其中包含两个文本字段和一个按钮。它应该看起来像这样。两个文本框靠得更近,按钮稍微向下。

这是我的代码。

struct ContentView: View {
    var body: some View {
        VStack {
            Spacer()
            InputTextField(title: "First Name", text: .constant(""))
            InputTextField(title: "Last Name", text: .constant(""))
            Spacer()
            ActionButton(title: "Login", action: {})
            Spacer()
        }
    }
}


struct InputTextField: View {
    let title: String
    
    @Binding var text: String
    
    var body: some View {
        VStack(alignment: .leading) {
            Text(title)
                .foregroundColor(.primary)
                .fontWeight(.medium)
                .font(.system(size: 18))
            
            HStack {
                TextField("", text: $text)
                    .frame(height: 54)
                    .textFieldStyle(PlainTextFieldStyle())
                    .cornerRadius(10)
            }
            .padding([.leading, .trailing], 10)
            .overlay(RoundedRectangle(cornerRadius: 10).stroke(Color.gray, lineWidth: 0.6))
        }
        .padding()
    }
}


struct ActionButton: View {
    let title: String
    var action: () -> Void

    var body: some View {
        Button(title) {
            action()
        }
        .frame(minWidth: 100, idealWidth: 100, maxWidth: .infinity, minHeight: 60, idealHeight: 60)
        .font(.system(size: 24, weight: .bold))
        .foregroundColor(.white)
        .background(Color.blue)
        .cornerRadius(10)
        .padding([.leading, .trailing])
        .shadow(color: Color.gray, radius: 2, x: 0, y: 2)
    }
}

我想将其嵌入 ScrollView 以便用户可以在键盘出现时上下滚动。

struct ContentView: View {
    var body: some View {
        ScrollView {
            VStack {
                Spacer()
                InputTextField(title: "First Name", text: .constant(""))
                InputTextField(title: "Last Name", text: .constant(""))
                Spacer()
                ActionButton(title: "Login", action: {})
                Spacer()
            }
        }
    }
}

这是我遇到这个问题的地方。当我在 ScrollView 中添加 VStack 时,所有内容都会缩小并显示在一起。似乎 SpacerScrollView.

中无效

我该如何解决这个问题?

Demo project

如您所见,Spacer 是否在 ScrollView 中时表现不同,或者换句话说,当它们可以扩展的轴是无限或有限时。

如果您希望内容适合时垂直居中,大于屏幕时滚动,我会这样做:

struct ContentView: View {
    var body: some View {
        VStack { // This new stack would vertically center the content
                 // (I haven't actually tried it though)
            ScrollView {
                VStack {
                    Spacer().size(height: MARGIN) // The minimum margin you want
                    InputTextField(title: "First Name", text: .constant(""))
                    InputTextField(title: "Last Name", text: .constant(""))
                    Spacer().size(height: SPACING)
                    ActionButton(title: "Login", action: {})
                    Spacer().size(height: MARGIN)
                }
            }
        }
    }
}

在这里,您需要通过如下给出最小高度来使内容伸展以填充整个滚动视图

struct ContentView: View {
  var body: some View {
    GeometryReader { gr in
        ScrollView {
            VStack {
                Spacer()
                InputTextField(title: "First Name", text: .constant(""))
                InputTextField(title: "Last Name", text: .constant(""))
                Spacer()
                ActionButton(title: "Login", action: {})
                Spacer()
            }
            .frame(minHeight: gr.size.height)
        }
    }
  }
}

这是输出: