Search code examples
iosswiftswiftuiscrollviewvstack

SwiftUI: Spacer doesn't work at ScrollView


How can I get space in VStack to pin the button at the bottom?

ScrollView {
        VStack() {
            Text("Title_1")
                .padding(.bottom, 35.0)
            Text("Title_2")
                .padding(.bottom, 32.0)
            Text("Title_3")
                .padding(.bottom, 27.0)
            
            Spacer()
            Button(action: { print("ACTION") }) {
                Text("OK")
                    .font(.title)
                    .fontWeight(.semibold)
                    .foregroundColor(Color.red)
                    
            }
            .frame(height: 35)
            .cornerRadius(8.0)
            .padding(.bottom, 25.0)
        }
        .frame(maxWidth: .infinity)
    }

what I have

what I want to have


Solution

  • Use GeometryReader

    A container view that defines its content as a function of its own size and coordinate space. https://developer.apple.com/documentation/swiftui/geometryreader

    GeometryReader { geometry in
        ScrollView {
            VStack() {
              -----
            }
            .frame(width: geometry.size.width, height: geometry.size.height)
        }
    }
    

    Doing so, the VStack is full-screen.


    You may not neeed to use ScrollView, because you do not need to scroll to see its content.

        var body: some View {
            
            VStack() {
                Text("Title_1")
                    .padding(.bottom, 35.0)
                Text("Title_2")
                    .padding(.bottom, 32.0)
                Text("Title_3")
                    .padding(.bottom, 27.0)
                
                Spacer()
                Button(action: { print("ACTION") }) {
                    Text("OK")
                        .font(.title)
                        .fontWeight(.semibold)
                        .foregroundColor(Color.red)
                    
                }
                .frame(height: 35)
                .cornerRadius(8.0)
                .padding(.bottom, 25.0)
            }
            .frame(maxWidth: .infinity)
        }
    
    

    But if your content's height is more than the screen height, the OK button is at the bottom, regardless. Hence, you do not need to do anything.