Reputation: 457
Major Edit to Clarify Question
What I want: For a Text
view aligned to the left or right of the screen to expand to a certain maximum width and when the text reaches that length it not go beyond that. When the text to be displayed gets too long, the Text
view just simply increase the height to account for the additional text. An example of this is in Apple's Messages app: Sent messages are aligned all the way to right, but even when they are very long there is still an empty space to their left (the width of the chat bubble only gets to like 75% of the screen's width).
Code I Have w/ some hardcoded values to provide example:
struct ContentView: View {
let messages = [
"Hello.",
"Hi",
"Text so long that it could reach all the way to the other side of the screen, we only want it to take up a width of about 75% of the screen though starting from the left. That is the main issue of this post.",
"Yeah. This message is also long enough to take up the full width of the screen, but for this one we want it to take up 75% of the screen starting all the way on the right side.",
"What are we gonna do.",
"IDK."
]
var body: some View {
VStack {
List {
ForEach(0...5, id: \.self) { number in
Text(messages[number])
.frame(maxWidth: .infinity, alignment: number % 2 == 0 ? .leading : .trailing)
}
}
}
}
}
So I am almost getting what I want, every other message is right aligned. But, when the string in the Text
view is long, the width of the Text
view expands all the way before the height starts expanding. I'd like for the width to only expand a set amount before the height starts expanding instead.
I understand that the expansion of the width of a Text
view to fit the text is normal behavior, but I'm wondering if there is a way to change that. The only thing I could think to try was changing maxWidth
, however that just causes the right edge of the .trailing
Text
to be moved to the left which is unwanted.
Upvotes: 5
Views: 9423
Reputation: 1426
Wrap your Text
element into the HStack
first and shrink other free space with the Spacer
. Then wrap HStack
container into the VStack
as main content view container and apply another view modifiers, if needed.
private func textContainerView(_ copy: String) -> some View {
VStack {
HStack {
Text(copy)
.multilineTextAlignment(.leading)
.foregroundColor(.gray)
.font(.body)
.padding(.all, 16)
Spacer()
}
}
.background(Color.white)
.cornerRadius(12)
}
Upvotes: 0
Reputation: 457
This is the code that finally worked for me. Using a fixed width Spacer
rather than somehow setting a maximum width for the Text
view.
var body: some View {
VStack {
List {
ForEach(0...5, id: \.self) { number in
HStack {
if number % 2 != 0 {
Spacer()
.frame(minWidth: 20, maxWidth: .infinity)
}
Text(messages[number])
if number % 2 == 0 {
Spacer()
.frame(minWidth: 20, maxWidth: .infinity)
}
}
}
}
}
}
Upvotes: 1
Reputation: 6500
ForEach(previouslyPlayed, id: \.self) { data in
Text(data.text)
.lineLimit(nil)
.multilineTextAlignment(.trailing)
.foregroundColor(ColorManager.mainText)
.font(.custom("Courier New", size: 14))
.fixedSize(horizontal: false, vertical: true)
}
Upvotes: 4