使 Button 跨越 VStack
Making Button span across VStack
我目前有以下 SwiftUI 视图:
HStack {
...
VStack {
TextField { ... }
SecureField { ... }
Button { ... }
}
...
}
我在 Button
中添加了 .background(Color.green)
,如您所见,视图与文本非常贴合。
我想知道是否有办法调整按钮的宽度,使其填满 VStack
- 类似于 UIStackView
的 .fill
模式。
我不确定是否有类似于 UIStackView
的 .fill
方法,但是,如果您想要做的是在 Button
(或任何视图那很重要)对我有用的是设置 frame
或 padding
.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 年的旧答案:
您可以将 HStack
与 Text
和 Spacer
一起使用以获得填充其父级宽度的 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)
否则,可点击区域不会拉伸。
我目前有以下 SwiftUI 视图:
HStack {
...
VStack {
TextField { ... }
SecureField { ... }
Button { ... }
}
...
}
我在 Button
中添加了 .background(Color.green)
,如您所见,视图与文本非常贴合。
我想知道是否有办法调整按钮的宽度,使其填满 VStack
- 类似于 UIStackView
的 .fill
模式。
我不确定是否有类似于 UIStackView
的 .fill
方法,但是,如果您想要做的是在 Button
(或任何视图那很重要)对我有用的是设置 frame
或 padding
.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 年的旧答案:
您可以将 HStack
与 Text
和 Spacer
一起使用以获得填充其父级宽度的 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)
否则,可点击区域不会拉伸。