George Ananda Eman
George Ananda Eman

Reputation: 3352

How do you create a multi-line text inside a ScrollView in SwiftUI?

Since List doesn't look like its configurable to remove the row dividers at the moment, I'm using a ScrollView with a VStack inside it to create a vertical layout of text elements. Example below:

ScrollView {
    VStack {
        // ...
        Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer mattis ullamcorper tortor, nec finibus sapien imperdiet non. Duis tristique eros eget ex consectetur laoreet.")
            .lineLimit(0)
    }.frame(width: UIScreen.main.bounds.width)
}

The resulting Text rendered is truncated single-line. Outside of a ScrollView it renders as multi-line. How would I achieve this inside a ScrollView other than explicitly setting a height for the Text frame ?

Upvotes: 56

Views: 18799

Answers (6)

blackjacx
blackjacx

Reputation: 10510

The following works for me with Beta 3 - no spacer, no width constraint, flexible height constraint:

ScrollView {
    VStack {
        Text(longText)
            .lineLimit(nil)
            .font(.largeTitle)
            .frame(idealHeight: .infinity)
    }
}

Upvotes: 3

Andre Carrera
Andre Carrera

Reputation: 2696

In Xcode 11 GM:

For any Text view in a stack nested in a scrollview, use the .fixedSize(horizontal: false, vertical: true) workaround:

ScrollView {
    VStack {
        Text(someString)
            .fixedSize(horizontal: false, vertical: true)
    }
}

This also works if there are multiple multiline texts:

ScrollView {
    VStack {
        Text(someString)
            .fixedSize(horizontal: false, vertical: true)
        Text(anotherLongString)
            .fixedSize(horizontal: false, vertical: true)
    }
}

If the contents of your stack are dynamic, the same solution works:

ScrollView {
    VStack {
        // Place a single empty / "" at the top of your stack.
        // It will consume no vertical space.
        Text("")
            .fixedSize(horizontal: false, vertical: true)

        ForEach(someArray) { someString in
            Text(someString)
              .fixedSize(horizontal: false, vertical: true)
        }
    }
}

Upvotes: 120

ScrollView {
    Text(LocalizedStringKey("Lorem Ipsum"))
        .font(.footnote)
        .foregroundColor(.white)
        .padding()
        .multilineTextAlignment(.center)
        .fixedSize(horizontal: false, vertical: true)
}

Upvotes: 0

Alexandru Motoc
Alexandru Motoc

Reputation: 704

The correct solution is to just make sure to set the alignment for your stack:

VStack(alignment: .leading)

ScrollView {
    VStack(alignment: .leading) {
        // ...
        Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer mattis ullamcorper tortor, nec finibus sapien imperdiet non. Duis tristique eros eget ex consectetur laoreet.")
            .lineLimit(0)
    }.frame(width: UIScreen.main.bounds.width)
}

This way you don't need the fixedSize as the layout is properly defined.

Upvotes: 1

kyis
kyis

Reputation: 241

You can force views to fill their ideal size, for example in a vertical ScrollView:

ScrollView {
    Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer mattis ullamcorper tortor, nec finibus sapien imperdiet non. Duis tristique eros eget ex consectetur laoreet.")
        .fixedSize(horizontal: false, vertical: true)
}

Feels a little better to me than modifying the frame.

Upvotes: 7

apphud
apphud

Reputation: 633

It seems like there is bug in SwiftUI. For now you have to specify height for your VStack container

ScrollView {
      VStack {
           // ...
               Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer mattis ullamcorper tortor, nec finibus sapien imperdiet non. Duis tristique eros eget ex consectetur laoreet.")
                    .lineLimit(nil)
            }.frame(width: UIScreen.main.bounds.width, height: 500)
       }

Upvotes: 3

Related Questions