Hi,
I noticed some unexpected layout behavior with Button in SwiftUI: the apparent horizontal padding/inset of a Button seems to change depending on the length of its text label.
Here is a minimal example:
VStack {
Button {
} label: {
Text("我是一段很长的文字")
.lineLimit(nil)
.frame(maxWidth: .infinity, alignment: .leading)
.border(.red)
}
Button {
} label: {
Text("我是一段")
.lineLimit(nil)
.frame(maxWidth: .infinity, alignment: .leading)
.border(.red)
}
}
.frame(width: 100)
.border(.red)
In Preview, the outer VStack has a fixed width of 100pt, and both Button labels use:
.frame(maxWidth: .infinity, alignment: .leading)
The red border around each Text shows that the label itself is receiving the expected available width.
However, the two Buttons appear to have different horizontal insets between the Button's edge and the Text's edge, even though both Buttons are inside the same VStack and have the same layout configuration.
In other words, the Button's apparent internal padding seems to depend on the intrinsic width / length of the label:
┌────────────────────┐
│ ┌──────────────┐ │
│ │ Long text │ │
│ └──────────────┘ │
└────────────────────┘
┌────────────────────┐
│ ┌────────────┐ │
│ │ Short text │ │
│ └────────────┘ │
└────────────────────┘
What I find particularly confusing is that the label itself has:
.frame(maxWidth: .infinity)
so I would expect both Button labels to occupy the same available width.
I'm trying to understand whether this is expected behavior of the default Button style or a consequence of SwiftUI's layout proposal/intrinsic-size system.
Specifically:
- Why does the Button's apparent horizontal padding change based on the label's text length?
- Does the default
Buttonstyle intentionally use the label's intrinsic/ideal size when determining its content inset? - Is there an official SwiftUI API to specify a fixed horizontal content inset/padding for a Button, independent of the label's intrinsic size?
- If I want both Buttons to have exactly the same internal horizontal padding, what is the recommended SwiftUI approach?
- Is there a way to make the Button give its label the full proposed width before applying its own default styling/insets?
I'm aware that I can implement a custom ButtonStyle, but I'm specifically wondering whether there is an existing SwiftUI API or modifier intended for controlling this behavior while retaining the system Button style.
I'm seeing this behavior in recent versions of SwiftUI and would appreciate any clarification on the intended layout behavior and the recommended solution.
Thanks!