在SwiftUI中如何在ScrollView内创建多行文本?

54

因为目前看起来 List 不可配置以删除行分隔符,所以我正在使用一个 ScrollView,其中包含一个 VStack,以创建文本元素的垂直布局。以下是示例:

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

生成的文本呈现为截断单行。在ScrollView之外,它呈现为多行。我该如何在ScrollView中实现此效果,而不是显式地为Text框架设置高度?


如果您给“Text”设置宽度框架会发生什么? - Fogmeister
1
“Text”按预期缩小到指定的宽度。但仍然是单行@Fogmeister - George Ananda Eman
你可以根据宽度计算文本的高度,并将其设置到文本框中。这样就可以正常工作了。 - dinesh sharma
2
这是一个错误。有一个解决方法... https://icalvin.dev/post/403 - Fogmeister
5个回答

117

Xcode 11 GM 中:

对于嵌套在滚动视图中的堆栈中的任何Text视图,使用.fixedSize(horizontal: false, vertical: true)解决方法:

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

如果有多个多行文本,这也适用:

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

如果您的堆栈内容是动态的,同样的解决方案也适用:

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

错误在预览中不会抛出,对吧?因为在预览中它显示了与之前相同的截断行为...但是没有 Spacer() 就可以正常工作... - thisIsTheFoxe
太棒了!我一直在使用GeometryReader..但是得不偿失。 - Fernando Martínez
从beta 5开始,.infinity会导致崩溃,但是.frame(idealHeight: .greatestFiniteMagnitude)可以正常工作。 - dalton_c
2
我在一个滚动视图中有许多动态生成的视图,其中一些包含了其各自视图树下数层的文本。不幸的是,这些解决方案都不起作用——我仍然看到一堆文本字段压缩成一行。有人遇到过类似的问题吗?我使用的是Xcode的GM版本。 - neptune
1
为什么这个有效?将真和假的值反过来似乎更有意义,因为垂直高度应该是灵活而不是固定的。 - Jonathan.

7

您可以强制视图填充其理想大小,例如在垂直滚动视图中:

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

对我来说,这比修改框架好一点。


3
以下内容对于我来说是可行的,适用于Beta 3 - 无需间隔符,无需宽度限制,灵活的高度约束:
ScrollView {
    VStack {
        Text(longText)
            .lineLimit(nil)
            .font(.largeTitle)
            .frame(idealHeight: .infinity)
    }
}

3

看起来SwiftUI存在一个bug。目前你需要为你的VStack容器指定高度。

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

1

正确的解决方案是确保为您的堆栈设置对齐方式:

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

这样,您不需要使用fixedSize,因为布局已经被正确定义。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接