xcode SwiftUI:在ScrollView中放置LazyVStack或LazyHStack会导致口吃(苹果错误??)

oknwwptz  于 2023-02-13  发布在  Swift
关注(0)|答案(7)|浏览(89)

XCode版本12.4(12D4e)
每次我在ScrollView中实现惰性堆栈时都会遇到这种情况:
1.将LazyHStack添加到水平ScrollView或将LazyVStack添加到垂直ScrollView
1.添加足够的内容,使滚动视图的内容大小超出其界限

    • 方案1-将滚动视图拉出边界(就像您正在拉出以刷新一样)**
  • 预期行为 *:当滚动视图停留在您的手指下时,它的行为与预期一致
  • 观察到的行为 *:它会结巴会跳
    • 场景2-快速滚动到边缘,使其必须反弹**
  • 预期行为 *:弹得很平稳
  • 观察到的行为 *:当它到达边缘时会停止并抖动,但不会反弹
    • 我的理论**我的理论是,由于使用了Lazy堆栈,当一个视图离开屏幕时,它会从视图层次结构中删除,从而创建一个口吃。

我想知道是否有其他人遇到过这个问题?这是SwiftUI中的一个bug吗?我已经在不同的项目中可靠地复制了这个问题几个月了,最后我希望我能不使用懒惰栈。

    • 示例代码**
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日更新

我把视图中的所有内容都删除了,然后一个接一个地重新构建起来--当我在一个简单的Text元素周围放置一个VStack/HStack/ZStack时,LazyVStack就开始结巴了。
如果我把fixedSize(horizontal: false, vertical: true)添加到Text元素中,它似乎停止了口吃,但当我添加一个可变高度的UIViewRepresentable时,它又开始口吃。
看起来在LazyStack中,每个子视图都需要某种固定大小或纯SwiftUI视图才能工作。
我会继续查的必须...解决...

clj7thdc

clj7thdc1#

我收到了DTS的回复,他们确认这是一个bug,但没有解决方案。你可以参考我的反馈ID并提交一个反馈项。我想他们会用新的swift版本来解决这个问题,因为我认为这可能是一个遗留缺陷,可能会导致破坏性的更改。换句话说,它与本地组件和导航栏有关。他们必须破坏一些东西来修复它。这意味着iOS 14中的SwiftUI应用程序可能永远不兼容。但我只是猜测。如果我得到任何消息,我会让大家知道。它确实是一个主要的阻碍,完全破坏了用户体验。

zvms9eto

zvms9eto2#

我可以确认口吃问题在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)

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

rkkpypqq

rkkpypqq3#

我添加了一个透明矩形

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

而且它似乎解决了我在ScrollView下的LazyVStack中口吃的大部分问题。

u7up0aaq

u7up0aaq4#

这似乎仍然是IOS 16上的一个问题。我无法在模拟器上修复它,但user14518353的答案似乎在设备上工作。对于那些找不到提到的用户答案的人,请将此添加到onAppear或init-
UI滚动视图.外观().反弹=假
编辑:
虽然它看起来大多数是固定的,我已经设法重现了一次与上述修复的问题&添加矩形().前景颜色(. clear).框架(高度:1.0)到LazyVStack的顶部似乎也有帮助。目前我建议设置两个反弹和添加在矩形中,因为这种组合似乎是最好的修复我。

qni6mghb

qni6mghb5#

我有一个非常类似的问题,禁用edgesForExtendedLayout对我很有效。
如果在UIHostingController中使用SwiftUI视图,您可以尝试将以下内容添加到UIHostingController子类:

class MyViewController: UIHostingController<MyView> {

  init() {
        let view = MyView()
        super.init(rootView: view)
  }

  override func viewDidLoad() {
      super.viewDidLoad()
      edgesForExtendedLayout = []
  }

这在xcode 13.2.1和iOS 15.2下可重现

ogsagwnx

ogsagwnx6#

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

ni65a41a

ni65a41a7#

尝试禁用ScrollView反弹。将下面的行添加到onAppear或init中,
UIScrollView.appearance().bounces = false

相关问题