SwiftUI:将LazyVStack或LazyHStack放入ScrollView会导致口吃(Apple错误??)
XCode 版本 12.4 (12D4e)
每次在 ScrollView 中实现 Lazy 堆栈时,我都会遇到这个问题:
- 添加 a
LazyHStack到水平ScrollView或 aLazyVStack到垂直ScrollView - 添加足够的内容,使滚动视图的内容大小超出其边界
场景 1 - 将滚动视图拉出边界(就像拉动以刷新)
预期行为:当滚动视图停留在您的手指下时,它的行为与预期一致
观察到的行为:它口吃和跳跃
场景 2 - 快速滚动到边缘,使其必须弹跳
预期行为:弹跳顺畅
观察到的行为:到达边缘时停止并抖动,但不反弹
我的理论
我的理论是,由于使用了 Lazy 堆栈,当视图离开屏幕时,它会从视图层次结构中移除,从而造成卡顿。
我想知道有没有其他人遇到过这种情况?这是 SwiftUI 中的错误吗?几个月来,我已经在不同的项目中可靠地重现了这一点,但最终还是不使用我希望可以使用的 Lazy 堆栈。
示例代码
ScrollView {
LazyVStack {
ForEach(viewModel.items) { items in
SomeView(viewModel: .init(context: viewModel.context, item: item))
}
}
注意:口吃只发生在滚动视图的顶部
** 2021 年 7 月 10 日更新**
这仍然发生在 iOS 15 版本 13.0 测试版 (13A5155e) 中。
在下面的视频中,注意滚动条的行为和到达底部时的卡顿:
https://youtu.be/z2pybl5yYqk
** 2021 年 7 月 19 日更新**
我把我认为的所有东西都撕掉了,然后一个一个地建立起来——一旦我VStack/HStack/ZStack在一个简单的Text元素周围放了一个,LazyVStack 就会开始卡顿。
如果我添加fixedSize(horizontal: false, vertical: true)到Text元素它似乎停止口吃。一旦我添加了一个UIViewRepresentable可变高度,它就会再次开始口吃。
似乎在 LazyStack 中,每个孩子都需要某种固定大小或纯粹的 SwiftUI 视图才能工作。
我会继续挖掘。必须……解决……
回答
我收到了 DTS 的回复,他们确认这是一个错误,但没有解决方法。您可以参考我的反馈 ID 并提交反馈项目。我想他们会用新的 swift 版本解决这个问题,因为我认为这可能是一个遗留缺陷,可能会导致重大更改。换句话说,它与原生组件和导航栏有关,他们必须打破一些东西才能修复它。这意味着 iOS 14 中的 SwiftUI 应用程序可能永远不兼容。但我只是猜测。如果我有任何消息,我会通知所有人。这确实是一个主要的障碍,并完全破坏了 IMO 的用户体验。