SwiftUI中滚动视图中VStack中元素的神秘间距或填充
我不明白为什么在使用SwiftUI中滚动视图中VStack中元素的神秘间距或填充,swiftui,Swiftui,我不明白为什么在使用GeometryReader渲染自定义水平分隔线时,在VStack中的ForEach元素之间有额外的垂直间距,该元素位于ScrollView中 ScrollView { ForEach(self.model1.elements, id: \.self) { element in VStack.init(alignment: .leading, spacing: 0) {
GeometryReader
渲染自定义水平分隔线时,在VStack
中的ForEach
元素之间有额外的垂直间距,该元素位于ScrollView
中
ScrollView {
ForEach(self.model1.elements, id: \.self) { element in
VStack.init(alignment: .leading, spacing: 0) {
// Text("test") // image 3: works correctly
// .background(Color.blue)
GeometryReader { geometry in
Path { path in
path.move(to: .init(x: 0, y: 0))
path.addLine(to: .init(x: geometry.size.width, y: 0))
}
.strokedPath(.init(lineWidth: 1, dash: [1,2]))
}
// .frame(maxHeight: 1) // image 2: uncommenting this line doesn't fix the spacing
.foregroundColor(.red)
.background(Color.blue)
HStack {
Text("\(element.index+1)")
.font(.system(.caption, design: .rounded))
.frame(width: 32, alignment: .trailing)
Text(element.element)
.font(.system(.caption, design: .monospaced))
.frame(maxWidth:nil)
Spacer()
}
.frame(maxWidth:nil)
.background(Color.green)
}
.border(Color.red)
}
}
上述代码产生以下结果:
使用.frame(maxHeight:1)
时,蓝色填充消失,但连续的HStack
s之间仍有空白。我希望垂直间距与此图像中的一样,即0。此图像是通过取消注释
文本(“测试”)
源代码,并注释GeometryReader
代码来实现的。
我使用的是Xcode
11.3.1(11C504)
如果我理解您的最终目标,那就是让上面的每一行用虚线隔开,中间没有填充物,如下所示:
在这种情况下,你应该把这些线放在背景中。例如:
ScrollView {
VStack(alignment: .leading) {
ForEach(self.elements, id: \.self) { element in
HStack {
Text("\(element.index+1)")
.font(.system(.caption, design: .rounded))
.frame(width: 32, alignment: .trailing)
Text(element.element)
.font(.system(.caption, design: .monospaced))
Spacer()
}
.background(
ZStack(alignment: .top) {
Color.green
GeometryReader { geometry in
Path { path in
path.move(to: .zero)
path.addLine(to: CGPoint(x: geometry.size.width, y: 0))
}
.strokedPath(StrokeStyle(lineWidth: 1, dash: [1,2]))
.foregroundColor(Color.red)
}
}
)
}
}
}
一个关键点是ScrollView不是一个垂直堆叠容器。它只需要获取其内容并使其可滚动。它在代码中的内容是ForEach,它生成视图;它并不是真的打算把它们摆出来。因此,当您将ScrollView与ForEach组合在一起时,没有任何东西真正负责按您想要的方式放置视图。要垂直堆叠视图,需要VStack
您也可以将其应用于您的结构,但添加另一个VStack,并获得相同的结果:
ScrollView {
VStack(spacing: 0) { // <---
ForEach(self.elements, id: \.self) { element in
VStack(alignment: .leading, spacing: 0) {
GeometryReader { geometry in
Path { path in
path.move(to: .init(x: 0, y: 0))
path.addLine(to: .init(x: geometry.size.width, y: 0))
}
.strokedPath(.init(lineWidth: 1, dash: [1,2]))
}
.foregroundColor(.red)
.frame(height: 1)
HStack {
Text("\(element.index+1)")
.font(.system(.caption, design: .rounded))
.frame(width: 32, alignment: .trailing)
Text(element.element)
.font(.system(.caption, design: .monospaced))
.frame(maxWidth:nil)
Spacer()
}
}
.background(Color.green) // <-- Moved
}
}
}
滚动视图{
VStack(间距:0){//一个简单的(间距:0)
的加法刚刚解决了一个小时徒劳的调试。这是一个救命的办法。非常感谢间距:0!这是一个非常奇怪和令人沮丧的行为。