使 Button 跨越 VStack

Making Button span across VStack

我目前有以下 SwiftUI 视图:

HStack {
  ...
  VStack {
    TextField { ... }
    SecureField { ... }
    Button { ... }
  }
  ...
}

我在 Button 中添加了 .background(Color.green),如您所见,视图与文本非常贴合。

我想知道是否有办法调整按钮的宽度,使其填满 VStack - 类似于 UIStackView.fill 模式。

我不确定是否有类似于 UIStackView.fill 方法,但是,如果您想要做的是在 Button(或任何视图那很重要)对我有用的是设置 framepadding

.frame(width: 300, alignment: .center)(我们也可以在这里设置高度,但如果不是,它应该能够根据按钮文本推断高度。

如果您不想设置任意宽度,您也可以 import UIKit 并使用 UIScreen 并获得设备的全宽。 (可能有一种 SwiftUI 方法可以获取它,但目前还没有找到)

.frame(width: UIScreen.main.bounds.width, alignment: .center)

然后你可以为一些喘息空间添加一点填充

.padding(.all, 20)

内边距的问题在于它会增加屏幕的额外宽度,因此我们在设置宽度时必须考虑在内。

(前导和尾部的 20 * 2 边)

.frame(width: UIScreen.main.bounds.width - 40, alignment: .center)

(当文本覆盖到屏幕末尾时或您的对齐方式为 .leading.trailing 时有喘息空间)

是这样的吗?

Button(action: {
    // Do your login thing here
}) {
    Capsule()
        .frame(height: 44)
        .overlay(Text("Login").foregroundColor(Color.white)).padding()
}

将按钮文本的框架设置为 UIScreen 的大小,然后在它之后设置背景颜色(确保在更改框架大小 之后完成所有样式更改,否则样式更改将仅在原始默认框架上可见)。框架大小将向上传播以将按钮的宽度也增加到屏幕的宽度。:

Button(action: {
                // Sign in stuff
            }) {
                Text("Sign In")
                .frame(width: UIScreen.main.bounds.width, height: nil, alignment: .center)
                .background(Color.green)
            }

您还可以在设置框架和背景之间添加一些负水平填充,以便从屏幕边缘偏移:

Button(action: {
                    // Sign in stuff
                }) {
                    Text("Sign In")
                    .frame(width: UIScreen.main.bounds.width, height: nil, alignment: .center)
                    .padding(.horizontal, -10.0)
                    .background(Color.green)
                }

最好的方法是通过 .frame(maxWidth: .infinity) https://developer.apple.com/documentation/swiftui/view-layout

如果您希望按钮不居中,您需要指定alignment
例如:.frame(maxWidth: .infinity, alignment: .leading)

Button(action: handleSignInAction) {
    Text("Sign In")
}
.frame(maxWidth: .infinity)
.background(Color.green)

2019 年的旧答案:

您可以将 HStackTextSpacer 一起使用以获得填充其父级宽度的 Button

Button(action: handleSignInAction) {
    HStack {
        Spacer()
        Text("Sign In")
        Spacer()
    }
}.background(Color.green)

如果您想坚持使用 SwiftUI 文档建议的方法,您需要使用 GeometryReader 并手动设置按钮宽度。几何体 reader 会针对不同的设备和旋转更新其属性。

GeometryReader { geometry in
     Button().frame(width: geometry.size.width, height: 100)
}

@d.felber 的回答差不多完成了,但是你需要在每一边都放置一个 Spacer() 来居中:

Button(action: {
    // TODO: ...
}) {
    HStack {
        Spacer()
        Text("Sign In")
        Spacer()
    }
}
.frame(maxWidth: .infinity)

对我有用。

如果你想让整个绿色区域都可以点击,使用frame(maxWidth: .infinity)像这样:

Button(action: {}) {
    Text("Sign In")
        .frame(maxWidth: .infinity)
}
.background(Color.green)

不是这样的:

Button(action: {}) {
    Text("Sign In")
}
.frame(maxWidth: .infinity)
.background(Color.green)

否则,可点击区域不会拉伸。