I have a Text with a background (which is just a coloured bubble), and I'm trying to restrict its maxWidth to some width, say 200 for this example.
I'm running into a problem with .frame(..., maxWidth: ...).
Expected Behvaiour
- smaller messages are as big as they need to be
- larger messages will have a width up to the
maxWidthand will wrap without text being truncated
Actual Behaviour
- no matter in which order the
.background()and.frame()modifiers are applied, theTextis always drawn as what I have set themaxWidthto be.
In more detail:
Applying the .background() before the .frame(maxWidth: 200):
Text(...)
.fixedSize(horizontal: false, vertical: true)
.background(
Rectangle()
)
.frame(maxWidth: 200)
This results in the frame of all the Texts being of width 200 - which I'm not understanding. I understand that the background is applied before, so the background size is correct, but why does the frame become the maximum width? Am I misunderstanding how the maxWidth: frame works?
This behaviour is the exact same without the .fixedSize() modifier, as all that does is prevent the text from truncating into ...
Applying the .background() after the .frame(maxWidth: 200):
Text(...)
.fixedSize(horizontal: false, vertical: true)
.frame(maxWidth: 200)
.background(
Rectangle()
)
This shows the behaviour again, but this time with the background also affected by the frame. The modifier stacking behaviour is expected, but again, I'm not sure why the Text is expanding to the maxWidth.
For further information, these Texts are within an HStack with a Spacer() on the left side. The HStacks are within a larger VStack ScrollView.
Removing the HStack, Spacer() or the ScrollView/VStack does not change this behaviour.
I have tried giving it a minWidth and applying other modifiers to no avail. Any help is appreciated, as I feel that I'm missing something very obvious!
Thanks.
Edit: greater concision.
CodePudding user response:
You should apply .frame(maxWidth:) to the VStack, not to each Text.
struct TestView: View {
var body: some View {
VStack {
HStack {
MyText(text: "111")
MyText(text: "111")
}
MyText(text: "222222222")
MyText(text: "3333333333333")
MyText(text: "Long long long long long long long long long long text")
}
.frame(maxWidth: 200) // << there
}
struct MyText: View {
var text: String
var body: some View {
Text(text)
.padding(6)
.background(
Rectangle()
.fill(.yellow)
)
.border(.blue)
}
}
}
The blue border represents the actual Text frame sizes.

If you need a trailing alignment, then you should to set it in VStack(alignment: .trailing).

If you also need a trailing alignment inside Text frame, you can apply .multilineTextAlignment(.trailing) to Text.



