ScrollView 内的 LazyVStack 中具有可变高度的内容会导致口吃/跳跃 [英] Content with variable height in a LazyVStack inside a ScrollView causes stuttering / jumping

查看:27
本文介绍了ScrollView 内的 LazyVStack 中具有可变高度的内容会导致口吃/跳跃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

XCode 13.0 测试版 (13A5155e)&针对 iOS 14 或 15

XCode Version 13.0 beta (13A5155e) & Targeting iOS 14 or 15

我的目标是在 SwiftUI 中创建一个聊天视图.这需要创建一个包含不同高度内容的 ScrollView.

My goal is to create a chat view in SwiftUI. This requires creating a ScrollView with content of varying heights .

经过大量调试后,我确定如果您在 ScrollView 中有没有固定高度的视图,当您滚动到视图顶部时它会卡顿.

After extensive debugging, I've determined that if you have views within the ScrollView that do not have a fixed height, it will stutter when you scroll to the top of the view.

––––

项目: 下载这个项目并亲自尝试

struct Message: Identifiable {
  let id = UUID()
  var text: String
}

struct ContentView: View {
  @State var items: [Message] = MockData.randomMessages(count: 100)
  
  var body: some View {
    VStack {
      Button("Shuffle items") {
        items = MockData.randomMessages(count: 100)
      }
      ScrollView {
        LazyVStack(spacing: 10) {
          ForEach(items) { item in
            Text(item.text)
              .background(colors.randomElement()!)
          }
        }
      }
    }
  }
}

我现在的结论是 LazyVStack 仅适用于具有固定高度的子视图.仅此问题就阻碍了 SwiftUI 的生产就绪.

My conclusion right now is that LazyVStack only works with child views that have fixed height. This issue alone prevents SwiftUI from being production ready.

有没有其他人解决过这个问题?

Has anyone else tackled this?

Apple 的回复(2021 年 7 月 27 日):

"在您的 Mac 目标上,这一切正常,但我发现 iOS 上存在滚动问题.这个问题绝对是 iOS 上 SwiftUI 的一个错误.我建议您不要重写您的应用程序,而是为您的 UIScrollView 使用 UIViewRepresentable(或者实际上 UITable/UICollection View 在这里最有意义).如果您使用可重用的视图,例如表或集合,这些问题几乎肯定会消失.您不需要重写您的应用程序,但如果此问题阻止发布,您应该添加一个 UIViewRepresentable."

"On your Mac target this all works but I see there are scrolling issues on iOS. This issue is definitely a bug with SwiftUI on iOS. I recommend that rather than rewrite your app you use a UIViewRepresentable for your UIScrollView (or actually UITable / UICollection View would make the most sense here). If you use a re-usable view such as a table or collection these issues will almost certainly go away. You shouldn't need to rewrite your app but you should add a UIViewRepresentable if this issue is preventing a release."

推荐答案

在 macos 12.beta、xcode 13.beta、目标 ios 15 和 macCatalyst 上没有任何问题.在 ios15 设备和 macos 12 上测试过.我也尝试使用 10000,效果很好.也许您的问题发生在较旧的 ios 和 macos 上.您可能对 Swift UI 被高频 @StateObject 更新淹没? 代码在 ios14 上有问题但在 ios15 上没有问题.

works without any problems on macos 12.beta, xcode 13.beta, target ios 15 and macCatalyst. Tested on ios15 devices and macos 12. I also tried using 10000, and that works well. Maybe your issue happens on older ios and macos. You maybe interested in Swift UI overwhelmed by high-frequency @StateObject updates? where code struggles on ios14 but not ios15.

您可以尝试其他方法,看看是否可以提高性能,例如:

You could try other ways to see if you can improve the performance, such as:

 ForEach(items.indices, id: \.self) { index in
     Text(items[index]).background(colors.randomElement()!)
 }

 ForEach(Array(items.enumerated()), id: \.0) { index, item in
     Text(item).background(colors.randomElement()!)
 }

这篇关于ScrollView 内的 LazyVStack 中具有可变高度的内容会导致口吃/跳跃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆