簡體   English   中英

SwiftUI:將 LazyVStack 或 LazyHStack 放入 ScrollView 會導致卡頓(Apple 錯誤??)

[英]SwiftUI: Putting a LazyVStack or LazyHStack in a ScrollView causes stuttering (Apple bug??)

XCode 版本 12.4 (12D4e)

每次在 ScrollView 中實現 Lazy 堆棧時,我都會遇到這個問題:

  1. LazyHStack添加到水平ScrollView或將LazyVStack到垂直ScrollView
  2. 添加足夠的內容,使滾動視圖的內容大小超過其邊界

場景 1 - 將 scrollview 拉出邊界(就像拉動刷新一樣)

預期行為:滾動視圖停留在您的手指下時,它的行為符合預期

觀察到的行為:它結巴和跳躍

場景 2 - 快速滾動到邊緣,因此它必須反彈

預期行為:平穩反彈

觀察到的行為:它到達邊緣時停止並抖動,但不會反彈

我的理論我的理論是,由於使用了惰性堆棧,當視圖離開屏幕時,它會從視圖層次結構中刪除,從而造成卡頓。

我想知道是否還有其他人遇到過這種情況? 這是 SwiftUI 中的錯誤嗎? 我已經在不同的項目中可靠地復制了幾個月,並最終沒有使用我希望我可以使用的惰性堆棧。

示例代碼

        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 日更新**

我把我視圖中的所有東西都撕掉了,然后一個一個地重新構建它——當我在一個簡單的Text元素周圍放置一個VStack/HStack/ZStack時,LazyVStack 就開始卡頓了。

如果我將fixedSize(horizontal: false, vertical: true)添加到Text元素,它似乎會停止卡頓。 一旦我添加了一個可變高度的UIViewRepresentable ,它就會再次開始卡頓。

似乎在 LazyStack 中,每個孩子都需要某種固定大小或純粹的 SwiftUI 視圖才能工作。

我會繼續挖掘。必須...解決...

我收到了 DTS 的回復,他們確認這是一個錯誤,但沒有解決方法。 您可以參考我的反饋 ID 並提交反饋項目。 我想他們會用新的 swift 版本解決這個問題,因為我認為這可能是一個遺留缺陷,可能會導致重大變化。 換句話說,它與原生組件和導航欄有關,他們必須打破一些東西來修復它。 這意味着 iOS 14 中的 SwiftUI 應用程序可能永遠不兼容。 但我只是推測。 如果我得到任何消息,我會告訴大家。 這真的是一個主要的障礙,完全破壞了 IMO 的用戶體驗。

我已經確認問題在 iOS 15 中得到解決。不確定這是否有幫助,但也使用 Xcode 13 重新編譯了應用程序。

我可以確認 iOS 15 和 Xcode 13 中仍然存在口吃問題。我不確定是什么原因造成的,但它似乎與 LazyStacks 創建和布局項目的方式有關。

這是重現問題的 MWE:

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

在這個例子中,紅色的框架看起來“足夠寬”,在屏幕前緣反彈時會導致卡頓。

稍微減小寬度會使結巴 go 消失:

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 上進行了測試。對於這個特定的示例,問題僅發生在設備上(可能是因為我在模擬器上滾動速度不夠快)。 但是我在模擬器上更復雜的視圖上也遇到了這個問題。

嘗試禁用 ScrollView 反彈。 在 onAppear 或 init 中添加以下行,

UIScrollView.appearance().bounces = false

我添加了一個清晰的矩形

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

它似乎解決了我在 ScrollView 下的 LazyVStack 中遇到的大部分問題。

我有一個非常相似的問題,禁用edgesForExtendedLayout對我有用。

如果 SwiftUI 視圖在 UIHostingController 中使用,您可以嘗試將以下內容添加到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 下是可重現的

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM