31

XCode 版本 12.4 (12D4e)

每次我在 ScrollView 中实现 Lazy 堆栈时都会遇到这种情况:

  1. 将 a 添加LazyHStack到水平ScrollView或将 a添加LazyVStack到垂直ScrollView
  2. 添加足够的内容以使滚动视图的内容大小超出其范围

场景 1 - 将滚动视图拉出边界(就好像你在拉动刷新一样)

预期的行为:它的行为与预期的滚动视图保持在您的手指下一样

观察到的行为:口吃和跳跃

场景 2 - 快速滚动到边缘,使其必须反弹

预期行为:它平稳地弹跳

观察到的行为:当它到达边缘时它会停止并抖动,但不会反弹

我的理论 我的理论是,由于使用了惰性堆栈,当视图离开屏幕时,它会从视图层次结构中删除,从而产生口吃。

我想知道是否有其他人遇到过这种情况?这是 SwiftUI 中的错误吗?几个月来,我已经在不同的项目中可靠地复制了这一点,最终不使用我希望可以的 Lazy 堆栈。

示例代码

        ScrollView {
          LazyVStack {
            ForEach(viewModel.items) { items in
              SomeView(viewModel: .init(context: viewModel.context, item: item))
            }
          }

注意:口吃只发生在滚动视图的顶部

** 2021 年 7 月 10 日更新**

这仍然在 iOS 15 版本 13.0 beta (13A5155e) 中发生。

在下面的视频中,请注意滚动条的行为和我们到达底部时的卡顿:

https://youtu.be/z2pybl5yYqk

** 2021 年 7 月 19 日更新**

我把视图中的所有东西都撕掉并一个一个地构建起来——只要我VStack/HStack/ZStack在一个简单的Text元素周围放置一个,LazyVStack 就会开始卡顿。

如果我添加fixedSize(horizontal: false, vertical: true)Text元素中,它似乎停止了口吃。一旦我添加一个UIViewRepresentable可变高度,它就会再次开始口吃。

似乎在 LazyStack 中,每个孩子都需要某种固定大小或纯粹的 SwiftUI 视图才能工作。

我会继续挖掘。必须...解决...

4

5 回答 5

9

我收到了 DTS 的回复,他们确认这是一个错误,但没有解决方法。您可以参考我的反馈 ID 并提交反馈项目。我想他们会用新的 swift 版本解决这个问题,因为我认为这可能是一个遗留缺陷,可能会导致重大变化。换句话说,它与原生组件和导航栏有关,他们必须打破一些东西来修复它。这意味着 iOS 14 中的 SwiftUI 应用程序可能永远不兼容。但我只是推测。如果我得到任何消息,我会告诉大家。这真的是一个主要的障碍,完全破坏了 IMO 的用户体验。

于 2021-04-09T18:28:57.527 回答
4

我可以确认带有 Xcode 13 的 iOS 15 中仍然存在口吃问题。我不确定是什么原因造成的,但它似乎与 LazyStacks 创建和布局项目的方式有关。

这是重现问题的 MWE:

ScrollView(.horizontal) {
    LazyHStack {
        Color.red.frame(width: 450)
        Color.green.frame(width: 250)
        Color.blue.frame(width: 250)
    }
}
.frame(width: 350)

在这个例子中,红色的框架看起来“足够宽”,在屏幕前缘反弹时会导致卡顿。

稍微减小宽度会使口吃消失:

ScrollView(.horizontal) {
    LazyHStack {
        Color.red.frame(width: 400)
        Color.green.frame(width: 250)
        Color.blue.frame(width: 250)
    }
}
.frame(width: 350)

注意:在带有 Xcode 13 beta 1 和 iOS 15 beta 1 的 iPhone Xs Max 上进行了测试。对于这个特定的示例,问题仅发生在设备上(可能是因为我在模拟器上滚动速度不够快)。但是我在模拟器上更复杂的视图上也遇到了这个问题。

于 2021-06-16T22:23:20.050 回答
1

我已确认该问题已在 iOS 15 中解决。不确定这是否有帮助,但也使用 Xcode 13 重新编译了该应用程序。

于 2021-06-08T23:41:48.957 回答
0

尝试禁用 ScrollView 反弹。在 onAppear 或 init 中添加以下行,

UIScrollView.appearance().bounces = false

于 2021-10-19T22:41:26.677 回答
-1

我添加了一个清晰的矩形

ScrollView {
    LazyVStack {
        Rectangle().foregroundColor(.clear).frame(height: 1.0)
        ...
    }
}

它似乎解决了我在 ScrollView 下的 LazyVStack 中遇到的大部分问题。

于 2021-10-27T11:41:14.213 回答