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
maxWidth
and will wrap without text being truncated
Actual Behaviour
- no matter in which order the
.background()
and.frame()
modifiers are applied, theText
is always drawn as what I have set themaxWidth
to 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 Text
s 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 Text
s are within an HStack
with a Spacer()
on the left side. The HStack
s 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
.