简体   繁体   English

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

[英]Content inside VStack shrinks when embedded inside a ScrollView in SwiftUI

I have a simple login screen with two textfield and a button.我有一个带有两个文本字段和一个按钮的简单登录屏幕。 It should look like this.它应该看起来像这样。 The two textfields closer together and the button a little ways down.两个文本字段靠得更近,按钮向下一点。

在此处输入图像描述

Here is my code.这是我的代码。

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)
    }
}

I wanted to embed this inside a ScrollView so that user can scroll up and down when the keyboard comes up.我想将它嵌入到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()
            }
        }
    }
}

Here is where I'm coming across this issue.这是我遇到这个问题的地方。 When I add the VStack inside a ScrollView , all the content kind of shrinks and shows clumped together.当我在ScrollView中添加VStack时,所有内容都会缩小并显示聚集在一起。 Seems like the Spacer s have no effect when inside a ScrollView .似乎SpacerScrollView内时没有效果。

在此处输入图像描述

How can I fix this?我怎样才能解决这个问题?

Demo project 演示项目

Here, You need to make the content stretch to fill the whole scroll view by giving minimum height as below在这里,您需要通过给出最小高度来使内容拉伸以填充整个滚动视图,如下所示

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)
        }
    }
  }
}

Here is output:这是 output:

在此处输入图像描述

As you have found, Spacers behave differently when they are in a ScrollView or not, or put differently, when the axis they can expand on is infinite or finite.正如您所发现的,当它们在 ScrollView 中或不在 ScrollView 中时,Spacers 的行为会有所不同,或者当它们可以展开的轴是无限或有限时,它们的行为会有所不同。

If what you want is for your content to be centered vertically when it fits and scroll when it's larger than the screen, I would do something like this:如果你想要的是让你的内容在它适合时垂直居中并在它大于屏幕时滚动,我会做这样的事情:

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)
                }
            }
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM