我有一个LazyVStack
,有很多行。代码:
struct ContentView: View {
var body: some View {
ScrollView {
LazyVStack {
ForEach(0 ..< 100) { i in
Text("Item: \(i + 1)")
.onAppear {
print("Appeared:", i + 1)
}
}
}
}
}
}
最初只有大约40行在屏幕上可见,但是onAppear
被触发了77行。为什么会这样,为什么在它实际上在屏幕上可见之前调用它?我不明白为什么SwiftUI必须“预加载”它们。
有没有办法解决这个问题,或者如果是故意的,我怎么才能准确地知道最后一个可见的项(接受不同的行高)?
编辑
LazyVStack
的documentation声明:
堆栈是“惰性”的,因为堆栈视图直到需要在屏幕上呈现项目时才创建项目。
所以我猜这一定是个窃听器?
4条答案
按热度按时间xxb16uws1#
用documentation的话说,
onAppear
不应该是这样的:堆栈是“惰性”的,因为堆栈视图直到需要在屏幕上呈现项目时才创建项目。
但是,如果您有问题,让这个正常工作,请参阅我的解决方案如下。
虽然我不确定为什么
onAppear
s行被提前触发,但是我已经创建了一个变通的解决方案,读取滚动视图边界的几何形状和要跟踪的单个视图,比较它们,并设置它是否可见。在本例中,当滚动视图的边界中最后一个项目的上边缘可见时,
isVisible
属性会发生变化。由于安全区域的原因,当它在屏幕上可见时,isVisible
属性可能不会发生变化,但您可以根据需要进行更改。代码:
rlcwz9us2#
它的工作原理和我上面的评论一样。
o2g1uqev3#
这看起来难以置信,但只要添加一个包含ScrollView的GeometryReader就可以解决这个问题
wrrgggsh4#
在我的例子中,问题是我把我的
LazyVStack
放在ScrollView
中,而ScrollView
又放在另一个ScrollView
中(很容易失去它的踪迹)。