Swiftui Vstack和间隔者不根据文档行为
在 SwiftUI Apple Watch 应用程序中,我们需要一些在垂直滚动视图中对齐的文本,以便:
- 如果内容很小,则应将其放置在屏幕底部。
- 如果内容不适合屏幕的下半部分,它应该在底部延伸到屏幕之外,这样用户就必须向下滚动才能查看其余的内容。
到目前为止,我的看法是:
import SwiftUI
struct ContentView: View {
var body: some View {
GeometryReader { geometry in
ZStack {
ScrollView(.vertical) {
VStack(alignment: .leading, spacing: 0) {
Spacer()
.frame(minHeight: geometry.size.height / 2)
Text("Title")
.bold()
.background(.red.opacity(0.2))
Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.")
.background(.red.opacity(0.2))
}
.frame(minHeight: geometry.size.height - 20)
.background(.blue.opacity(0.4))
}
}
.padding(10)
.frame(width: geometry.size.width, height: geometry.size.height)
}
.ignoresSafeArea()
}
}
如您所见,Spacer
和 frame(minHeight: ...)
部分用于将内容放置在底部。 ScrollView
的大小固定为整个屏幕。
但是,文本并未完整显示。它的外观如下:
如您所见,内容并非从屏幕中间开始。显然,Spacer
变得大于其 minHeight
。但是,Spacer
据记录仅占用 VStack
中的多余空间。该 VStack
中没有任何多余空间,因此 Spacer
的高度应仅与其 minHeight
一样高。
我缺少什么?
这是滚动到底部时的样子:
为什么此文本被剪裁?
In a SwiftUI Apple Watch app, we need some text aligned in a vertical scroll view such that:
- if the content is small, it should be placed at the bottom of the screen.
- if the content does not fit into the lower half of the screen, it should extend off-screen at the bottom, such that the user has to scroll down to view the rest of the content.
Here's my take so far:
import SwiftUI
struct ContentView: View {
var body: some View {
GeometryReader { geometry in
ZStack {
ScrollView(.vertical) {
VStack(alignment: .leading, spacing: 0) {
Spacer()
.frame(minHeight: geometry.size.height / 2)
Text("Title")
.bold()
.background(.red.opacity(0.2))
Text("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.")
.background(.red.opacity(0.2))
}
.frame(minHeight: geometry.size.height - 20)
.background(.blue.opacity(0.4))
}
}
.padding(10)
.frame(width: geometry.size.width, height: geometry.size.height)
}
.ignoresSafeArea()
}
}
As you can see, the Spacer
and the frame(minHeight: ...)
part serve to place the content on the bottom. The ScrollView
's size is fixed to the whole screen.
However, the text is not displayed in full. Here's how it looks:
As you can see, the content does not start in the middle of the screen. Apparently the Spacer
gets larger than its minHeight
. However, the Spacer
is documented to only take excess space in a VStack
. There is not any excess space in that VStack
, so the Spacer
should only be as tall as its minHeight
.
What am I missing?
And here's how it looks when scrolled to the bottom:
Why is this text clipped?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
解决此问题的最重要部分是布局优先级。为了防止
spacer
无限扩展(因为scrollview
将为其内容提供多大空间),我们需要定义优先级。在不定义优先级的情况下,默认情况下,SwiftUi似乎只是在spacer
和所有文本
s 50/50之间均匀地分布了布局。我们可以降低
spacer
使用layoutpriority(_:)
修饰符。进行了一些其他次要调整,例如为vstack
设置最小高度,因此短期时,文本会对准底部。完整代码:
结果:
The most important part to fix this is the layout priority. To prevent the
Spacer
from infinitely expanding (becauseScrollView
will give however much space its contents want) we need to define which takes priority. Without defining priority, by default SwiftUI appears to just evenly distribute the layout between theSpacer
and all theText
s 50/50.We can reduce the priority of the
Spacer
expanding with thelayoutPriority(_:)
modifier. A few other minor adjustments were made, such as setting a minimum height for theVStack
so the text aligns to the bottom when it is short.Full code:
Result:
您根本不需要垫片,而是可以通过框架对齐来进行对齐,这在
用Xcode 13.2测试的情况下更合适。
You don't need spacer at all, instead alignment can be done by frame alignment, which is more appropriate in considered scenario
Tested with Xcode 13.2