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

Solution 1:

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)
        }
    }
}

Solution 2:

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.

Solution 3:

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)
       }

Solution 4:

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)
    }
}