cle*_*bit 1 user-interface ios swift swiftui
我正在尝试创建2个等宽的按钮,两个按钮垂直放置。它看起来应该像这样:
我将2放置Buttons在VStack其中,它会自动扩展到较大按钮的宽度。我正在尝试做的是将按钮的宽度扩展为,以填充的宽度VStack,但这是我得到的:
VStack(alignment: .center, spacing: 20) {
NavigationLink(destination: CustomView()) {
Text("Button")
}.frame(height: 44)
.background(Color.primary)
Button(action: { self.isShowingAlert = true }) {
Text("Another Button")
}.frame(height: 44)
.background(Color.primary)
}.background(Color.secondary)
Run Code Online (Sandbox Code Playgroud)
设置宽度将其VStack展开,但是按钮无法展开以适合:
VStack(alignment: .center, spacing: 20) {
...
}.frame(width: 320)
.background(Color.secondary)
Run Code Online (Sandbox Code Playgroud)
所以我的问题是:
除了手动设置布局中每个项目的框架外,还有其他方法吗?
我宁愿不必指定每一个,因为这将变得难以管理。
小智 9
您必须maxWidth: .infinity在Text按钮内部使用框架修饰符,这将迫使按钮Button变得尽可能宽:
VStack(alignment: .center, spacing: 20) {
NavigationLink(destination: CustomView()) {
Text("Button")
.frame(maxWidth: .infinity, height: 44)
}
.background(Color.primary)
Button(action: { self.isShowingAlert = true }) {
Text("Another Button")
.frame(maxWidth: .infinity, height: 44)
}
.background(Color.primary)
}.background(Color.secondary)
Run Code Online (Sandbox Code Playgroud)
这在 iOS 中有效,但在使用默认按钮样式(使用 AppKit 的 )的 macOS 中无效NSButton,因为它拒绝变得更宽(或更高)。macOS 中的技巧是使用.buttonStyle()按钮上的修饰符(或NavigationLink)并创建您自己的自定义按钮样式,如下所示:
struct MyButtonStyle: ButtonStyle {
func makeBody(configuration: Configuration) -> some View {
configuration.label
.background(configuration.isPressed ? Color.blue : Color.gray)
}
}
Run Code Online (Sandbox Code Playgroud)
必须将框架修改器应用于视图而不是按钮本身的原因Text是,按钮更愿意坚持其内容的大小,而不是包含按钮的视图建议的大小。这意味着,如果您将框架修改器应用于按钮而不是按钮内部Text,则按钮实际上将保持与 相同的大小,并且Text返回的视图.frame将扩展以填充包含的视图的宽度它,因此您将无法点击/单击视图边界之外的按钮Text。
设置.infinity为maxWidth,该frame(minWidth: maxWidth: minHeight:)API可用于使子视图展开以填充:
VStack(alignment: .center, spacing: 20) {
NavigationLink(destination: CustomView()) {
Text("Button")
}.frame(minWidth: 100, maxWidth: .infinity, minHeight: 44)
.background(Color.primary)
Button(action: { self.isShowingAlert = true }) {
Text("Another Button")
}.frame(minWidth: 100, maxWidth: .infinity, minHeight: 44)
.background(Color.primary)
}.frame(width: 340)
.background(Color.secondary)
Run Code Online (Sandbox Code Playgroud)
从 iOS 17 开始,正确的方法是使用.containerRelativeFrame修饰符,因为在框架上使用.infinity宽度实际上会将父框架推向无限宽度。
所以它会是这样的:
Button { } label: {
Text("Match Parent")
.foregroundStyle(.white)
.containerRelativeFrame(.horizontal) // This should be inside the `label` parameter of the `button`. Otherwise it would be NOT touchable
.padding(-10) // This is here to make space to the edges. Yes it should have a NEGATIVE value
}
.frame(height: 56)
.background(.red)
Run Code Online (Sandbox Code Playgroud)
