I've just started using SwiftUI with the retail build. I cannot get one of my text views to automatically expand into multiple lines. I've read many thread on SO and HackingWithSwift but cannot get it to work. I think perhaps it might be tied to my other frames but I'm not sure where to start
struct Message: View {
var body: some View {
ZStack() {
Color.blue.cornerRadius(8)
VStack(alignment: .leading, spacing: 8) {
Text("Lorem Ipsum")
.foregroundColor(.white)
.bold()
.font(.system(size: 20))
Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Donec enim diam vulputate ut pharetra. Sed turpis tincidunt id aliquet risus feugiat in. Interdum velit laoreet id donec ultrices tincidunt arcu non. Lorem END")
.foregroundColor(.white)
.lineLimit(nil)
Text("Sent to Group1 by iShaymus")
.foregroundColor(.white)
.italic()
.opacity(0.5)
.font(.system(size: 12))
}
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .topLeading)
.padding(12)
}
}
}
I've tried applying frames to the Text()
. I've tried adding .font(.body)
. I've tried setting .lineLimit(100)
. None of them worked. The output is always as follows:
The entire body string is noticeably longer:
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Donec enim diam vulputate ut pharetra. Sed turpis tincidunt id aliquet risus feugiat in. Interdum velit laoreet id donec ultrices tincidunt arcu non. Lorem END
This is the working code thanks to Marc
import SwiftUI
struct Message: View {
@State var title = ""
@State var messageBody = ""
@State var sentBy = ""
@State var targetSite = ""
var body: some View {
VStack(alignment: .leading, spacing: 8) {
Text(title)
.foregroundColor(.white)
.bold()
.font(.system(size: 20))
Text(messageBody)
.foregroundColor(.white)
.fixedSize(horizontal: false, vertical: true)
Text("Sent to \(targetSite) by \(sentBy)")
.foregroundColor(.white)
.italic()
.opacity(0.5)
.font(.system(size: 12))
}
.frame(minWidth: 0, maxWidth: .infinity, alignment: .topLeading)
.padding(12)
.background(Color.blue)
.cornerRadius(10)
}
}
I think this is what you are looking for. Use .fixedSize(horizontal: false, vertical: true)
as required.
struct Message: View {
var body: some View {
ZStack() {
Color.blue.cornerRadius(8)
VStack(alignment: .leading, spacing: 8) {
Text("Lorem Ipsum")
.foregroundColor(.white)
.bold()
.font(.system(size: 20))
Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Donec enim diam vulputate ut pharetra. Sed turpis tincidunt id aliquet risus feugiat in. Interdum velit laoreet id donec ultrices tincidunt arcu non. Lorem END")
.foregroundColor(.white)
.fixedSize(horizontal: false, vertical: true)
Text("Sent to Group1 by iShaymus")
.foregroundColor(.white)
.italic()
.opacity(0.5)
.font(.system(size: 12))
}
// .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity, alignment: .topLeading)
.padding(12)
}
.fixedSize(horizontal: false, vertical: true)
}
}
Your code doesn't match your screenshot so I can't test this exactly but I think what you want here is the layout priority modifier (.layoutPriority(1)
).
Use this modifier to give priority to spacing when the views are being laid out.
(Excerpt from "SwiftUI Views" Book)
Take a look at the comments in this code:
struct LayoutPriority_Intro: View {
var body: some View {
VStack(spacing: 20) {
Text("Layout Priority").font(.largeTitle)
Text("Introduction").foregroundColor(.gray)
Text("Use layout priority to tell the parent which child views get priority when it comes to assigning layout space.")
.layoutPriority(1) // Second highest priority
.frame(maxWidth: .infinity)
.padding()
.background(Color.yellow)
.foregroundColor(.black)
Text("No layout priority (default is 0)")
VStack(alignment: .leading, spacing: 8) {
HStack {
Image("profile2").mask(Circle())
Text("Janice Okoro").font(.largeTitle)
}
Text("Lorem ipsum dolor amet laborum gastropub laboris magna.")
.font(.body)
}
.padding()
.foregroundColor(.black)
.background(Color.yellow.cornerRadius(8))
.padding(.horizontal)
Text("Layout priority used")
VStack(alignment: .leading, spacing: 8) {
HStack {
Image("profile2").mask(Circle())
Text("Janice Okoro").font(.largeTitle)
}
Text("Lorem ipsum dolor amet laborum gastropub laboris magna.")
.font(.body)
}
// Give this view spacing priority over the other child views
.layoutPriority(2) // Highest priority
.padding()
.foregroundColor(.black)
.background(Color.yellow.cornerRadius(8))
.padding(.horizontal)
}
.font(.title)
.edgesIgnoringSafeArea(.bottom)
}
}
When I look at your code example it looks fine, but I'm suspecting if you replace .lineLimit(nil)
(which you don't need) with .layoutPriority(1)
then it might fix your issue.
If that doesn't help, put the layout priority on your VStack.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With