简体   繁体   English

SwiftUI:Spacer 在 ScrollView 中不起作用

[英]SwiftUI: Spacer doesn't work at ScrollView

How can I get space in VStack to pin the button at the bottom?如何在 VStack 中获得空间以将按钮固定在底部?

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我想拥有什么

The ScrollView gives that VStack infinite possible height. ScrollViewVStack提供了infinite可能的高度。 That's why the spacers not working.这就是垫片不起作用的原因。

The Fix:修复:

  • Give the VStack a minimumHeight that's the height of the ScrollView or ViewVStack一个minimumHeight ,它是ScrollViewView的高度
  • Also important to set the scrollview's width to be the view's width滚动视图的width设置为视图的width也很重要
GeometryReader { geometry in
    ScrollView(showsIndicators: false) {
        VStack {
        ...
        }
        .frame(minHeight: geometry.size.height)
    }.frame(width: geometry.size.width)
}

THIS WAY THE CONTENT WILL BE ABLE TO LAYOUT BEYOND THE VIEW's HEIGHT IF NEEDED这样,如果需要,内容将能够超出视图的高度

Use GeometryReader使用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 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.这样做,VStack 是全屏的。


You may not neeed to use ScrollView , because you do not need to scroll to see its content.您可能不需要使用ScrollView ,因为您无需滚动即可查看其内容。

    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.但是,如果您的内容的高度大于屏幕高度,则OK按钮位于底部,无论如何。 Hence, you do not need to do anything.因此,您无需执行任何操作。

Setting minHeight to screen height like other answers suggested works, but it brings issue where the ScrollView will no longer scroll beyond the screen height.像其他答案建议的那样将 minHeight 设置为屏幕高度是可行的,但它带来了 ScrollView 将不再滚动超出屏幕高度的问题。

Proper solution is wrapping a VStack outside of the ScrollView.正确的解决方案是将 VStack 包装在 ScrollView 之外。

For your case,对于你的情况,

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

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

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