Reputation: 1289
I want to limit the width of a Text to a given number. I thought that using frame(maxWidth:)
would do the job, however it does not behave as expected at all. It seems that setting a max width makes the text grow to this size, whatever the size it should be.
Here's a code snippet:
VStack(spacing: 20) {
VStack {
Text("Some Text")
.frame(maxWidth: 200)
}
.background(Color.yellow)
.border(.black, width: 1)
VStack {
Text("A longer text that should wrap to the next line.")
.frame(maxWidth: 200)
}
.background(Color.yellow)
.border(.black, width: 1)
}
Expected result:
Actual result:
Upvotes: 4
Views: 1516
Reputation: 257711
Assuming that we need a generic component which should work similarly with specified behavior independently of provided string, like
VStack(spacing: 20) {
TextBox("Some Text")
.background(Color.yellow)
.border(.black, width: 1)
TextBox("A longer text that should wrap to the next line.")
.background(Color.yellow)
.border(.black, width: 1)
}
then some run-time calculations required.
Here is a demo of possible solution (with real edge markers). Tested with Xcode 13.4 / iOS 15.5
Main part:
struct TextBox: View {
private let string: LocalizedStringKey
private let maxWidth: CGFloat
@State private var width: CGFloat
init(_ text: LocalizedStringKey, maxWidth: CGFloat = 200) { // << any default value
// ...
}
// ...
Text(string)
.background(GeometryReader {
Color.clear
.preference(key: ViewSideLengthKey.self, value: $0.frame(in: .local).size.width)
})
.onPreferenceChange(ViewSideLengthKey.self) {
self.width = min($0, maxWidth)
}
.frame(maxWidth: width)
Upvotes: 2
Reputation: 5084
The VStack
adjusts its width
to the max width
of its elements. This is the native behavior of the VStack
.
However, if you do the following you'll get the result you want:
VStack(spacing: 20) {
VStack {
Text("Some Text")
.background(Color.yellow)
.border(.black, width: 1)
}.frame(maxWidth: 200)
VStack {
Text("A longer text that should wrap to the next line.")
.frame(maxWidth: 200)
}.background(Color.yellow)
.border(.black, width: 1)
}
Upvotes: 1
Reputation: 3051
Generally, Text
automatically grow/shrink by itself. To solve your problem, just set maxWidth to your VStack
instead of Text
to control your maxWidth, then add backgrounds modifiers to your text instead.
Code is below the image:
VStack(spacing: 20) {
VStack {
Text("Some Text")
.background(Color.yellow)
.border(.black, width: 1)
}
.frame(maxWidth: 200)
VStack {
Text("A longer text that should wrap to the next line.")
.background(Color.yellow)
.border(.black, width: 1)
}
.frame(maxWidth: 200)
}
Upvotes: 4