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

SwiftSwiftui

Swift Problem Overview


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 ?

Swift Solutions


Solution 1 - Swift

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 - Swift

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 - Swift

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 - Swift

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

Solution 5 - Swift

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionGeorge Ananda EmanView Question on Stackoverflow
Solution 1 - SwiftAndre CarreraView Answer on Stackoverflow
Solution 2 - SwiftkyisView Answer on Stackoverflow
Solution 3 - SwiftapphudView Answer on Stackoverflow
Solution 4 - SwiftblackjacxView Answer on Stackoverflow
Solution 5 - SwiftAlexandru MotocView Answer on Stackoverflow